home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 1 / LIGHT-ROM 1 (Amiga Library Services)(1994).iso / ffdisks / d966.lha / UChessSrc / UChessSrc.lha / eval.c < prev    next >
C/C++ Source or Header  |  1994-02-11  |  77KB  |  3,074 lines

  1. /*
  2.  * eval.c - C source for GNU CHESS
  3.  *
  4.  * Copyright (c) 1988,1989,1990 John Stanback
  5.  * Copyright (c) 1992 Free Software Foundation
  6.  *
  7.  * This file is part of GNU CHESS.
  8.  *
  9.  * GNU Chess is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2, or (at your option)
  12.  * any later version.
  13.  *
  14.  * GNU Chess is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with GNU Chess; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23. #include "gnuchess.h"
  24. #include "ataks.h"
  25. int __aligned EADD = 0;
  26. int __aligned EGET = 0;
  27. int __aligned PUTVAR = false;
  28. #ifdef CACHE
  29. struct etable __far __aligned etab[2][ETABLE];
  30. #endif
  31.  
  32. extern short __aligned PCRASH,PCENTER;
  33. short __aligned QueenCheck[MAXDEPTH]; /* tom@izf.tno.nl */
  34. int __aligned myneweval=1;
  35. short int __aligned sscore[2];
  36. /* Backward pawn bonus indexed by # of attackers on the square */
  37. static const short __aligned BACKWARD[16] =
  38. {-6, -10, -15, -21, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28};
  39.  
  40. /* Bishop mobility bonus indexed by # reachable squares */
  41. static const short __aligned BMBLTY[14] =
  42. {-2, 0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 16, 16, 16};
  43.  
  44. /* Rook mobility bonus indexed by # reachable squares */
  45. static const short __aligned RMBLTY[15] =
  46. {0, 2, 4, 6, 8, 10, 11, 12, 13, 14, 14, 14, 14, 14, 14};
  47.  
  48. /* Positional values for a dying king */
  49. static const short __aligned DyingKing[64] =
  50. {0, 8, 16, 24, 24, 16, 8, 0,
  51.  8, 32, 40, 48, 48, 40, 32, 8,
  52.  16, 40, 56, 64, 64, 56, 40, 16,
  53.  24, 48, 64, 72, 72, 64, 48, 24,
  54.  24, 48, 64, 72, 72, 64, 48, 24,
  55.  16, 40, 56, 64, 64, 56, 40, 16,
  56.  8, 32, 40, 48, 48, 40, 32, 8,
  57.  0, 8, 16, 24, 24, 16, 8, 0};
  58.  
  59. /* Isoloted pawn penalty by rank */
  60. static const short __aligned ISOLANI[8] =
  61. {-12, -16, -20, -24, -24, -20, -16, -12};
  62.  
  63. /* table for King Bishop Knight endings */
  64. static const short __aligned KBNK[64] =
  65. #ifdef PRE4PL67
  66. {99, 90, 80, 70, 60, 50, 40, 40,
  67.  90, 80, 60, 50, 40, 30, 20, 40,
  68.  80, 60, 40, 30, 20, 10, 30, 50,
  69.  70, 50, 30, 10, 0, 20, 40, 60,
  70.  60, 40, 20, 0, 10, 30, 50, 70,
  71.  50, 30, 10, 20, 30, 40, 60, 80,
  72.  40, 20, 30, 40, 50, 60, 80, 90,
  73.  40, 40, 50, 60, 70, 80, 90, 99};
  74. #else
  75. {620, 560, 500, 440, 380, 320, 260, 240,
  76.  560, 520, 460, 400, 340, 280, 230, 260,
  77.  500, 460, 320, 280, 260, 220, 280, 320,
  78.  440, 400, 280, 200, 200, 260, 340, 380,
  79.  380, 340, 260, 200, 200, 280, 400, 440,
  80.  320, 280, 220, 260, 280, 320, 460, 500,
  81.  260, 230, 280, 340, 400, 460, 520, 560,
  82.  240, 260, 320, 380, 440, 500, 560, 620};
  83. #endif
  84.  
  85. /* penalty for threats to king, indexed by number of such threats */
  86. static const short __aligned KTHRT[36] =
  87. {0, -8, -20, -36, -52, -68, -80, -80, -80, -80, -80, -80,
  88.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
  89.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80};
  90.  
  91. /* King positional bonus inopening stage */
  92. static const short __aligned KingOpening[64] =
  93. {0, 0, -4, -10, -10, -4, 0, 0,
  94.  -4, -4, -8, -12, -12, -8, -4, -4,
  95.  -12, -16, -20, -20, -20, -20, -16, -12,
  96.  -16, -20, -24, -24, -24, -24, -20, -16,
  97.  -16, -20, -24, -24, -24, -24, -20, -16,
  98.  -12, -16, -20, -20, -20, -20, -16, -12,
  99.  -4, -4, -8, -12, -12, -8, -4, -4,
  100.  0, 0, -4, -10, -10, -4, 0, 0};
  101.  
  102. /* King positional bonus in end stage */
  103. static const short __aligned KingEnding[64] =
  104. {0, 6, 12, 18, 18, 12, 6, 0,
  105.  6, 12, 18, 24, 24, 18, 12, 6,
  106.  12, 18, 24, 30, 30, 24, 18, 12,
  107.  18, 24, 30, 36, 36, 30, 24, 18,
  108.  18, 24, 30, 36, 36, 30, 24, 18,
  109.  12, 18, 24, 30, 30, 24, 18, 12,
  110.  6, 12, 18, 24, 24, 18, 12, 6,
  111.  0, 6, 12, 18, 18, 12, 6, 0};
  112.  
  113. /* Passed pawn positional bonus */
  114. static const short __aligned PassedPawn0[8] =
  115. {0, 60, 80, 120, 200, 360, 600, 800};
  116. static const short __aligned PassedPawn1[8] =
  117. {0, 30, 40, 60, 100, 180, 300, 800};
  118. static const short __aligned PassedPawn2[8] =
  119. {0, 15, 25, 35, 50, 90, 140, 800};
  120. static const short __aligned PassedPawn3[8] =
  121. {0, 5, 10, 15, 20, 30, 140, 800};
  122.  
  123. /* Knight positional bonus */
  124. static const short __aligned pknight[64] =
  125. {0, 4, 8, 10, 10, 8, 4, 0,
  126.  4, 8, 16, 20, 20, 16, 8, 4,
  127.  8, 16, 24, 28, 28, 24, 16, 8,
  128.  10, 20, 28, 32, 32, 28, 20, 10,
  129.  10, 20, 28, 32, 32, 28, 20, 10,
  130.  8, 16, 24, 28, 28, 24, 16, 8,
  131.  4, 8, 16, 20, 20, 16, 8, 4,
  132.  0, 4, 8, 10, 10, 8, 4, 0};
  133.  
  134. /* Bishop positional bonus */
  135. static const short __aligned pbishop[64] =
  136. {14, 14, 14, 14, 14, 14, 14, 14,
  137.  14, 22, 18, 18, 18, 18, 22, 14,
  138.  14, 18, 22, 22, 22, 22, 18, 14,
  139.  14, 18, 22, 22, 22, 22, 18, 14,
  140.  14, 18, 22, 22, 22, 22, 18, 14,
  141.  14, 18, 22, 22, 22, 22, 18, 14,
  142.  14, 22, 18, 18, 18, 18, 22, 14,
  143.  14, 14, 14, 14, 14, 14, 14, 14};
  144.  
  145. /* Pawn positional bonus */
  146. static const short __aligned PawnAdvance[64] =
  147. {0, 0, 0, 0, 0, 0, 0, 0,
  148.  4, 4, 4, 0, 0, 4, 4, 4,
  149.  6, 8, 2, 10, 10, 2, 8, 6,
  150.  6, 8, 12, 16, 16, 12, 8, 6,
  151.  8, 12, 16, 24, 24, 16, 12, 8,
  152.  12, 16, 24, 32, 32, 24, 16, 12,
  153.  12, 16, 24, 32, 32, 24, 16, 12,
  154.  0, 0, 0, 0, 0, 0, 0, 0};
  155. #if !defined NOSCORESPACE
  156. #ifdef BLACKAG0
  157. /* Space positional bonus */
  158. static const short __aligned SpaceBonusB[64] =
  159. {0, 0, 0, 0, 0, 0, 0, 0,
  160.  0, 0, 2, 2, 2, 2, 0, 0,
  161.  1, 1, 2, 4, 4, 2, 1, 1,
  162.  0, 0, 3, 4, 4, 3, 0, 0,
  163.  0, 0, 5, 5, 5, 5, 0, 0,
  164.  0, 0, 4, 4, 7, 7, 0, 0,
  165.  0, 0, 0, 0, 0, 0, 0, 0,
  166.  0, 0, 0, 0, 0, 0, 0, 0};
  167. #elif defined BLACKAG1
  168. /* Space positional bonus */
  169. static const short __aligned SpaceBonusB[64] =
  170. {1, 1, 1, 1, 1, 1, 1, 1,
  171.  1, 1, 2, 2, 2, 2, 1, 1,
  172.  1, 1, 2, 3, 3, 2, 1, 1,
  173.  1, 1, 2, 4, 4, 2, 1, 1,
  174.  1, 1, 3, 5, 5, 3, 1, 1,
  175.  1, 1, 3, 6, 6, 3, 1, 1,
  176.  1, 1, 3, 7, 7, 3, 1, 1,
  177.  1, 1, 1, 1, 1, 1, 1, 1};
  178. #elif defined BLACKAG2
  179. /* Space positional bonus */
  180. static const short __aligned SpaceBonusB[64] =
  181. {1, 1, 1, 1, 1, 1, 1, 1,
  182.  1, 1, 2, 2, 2, 2, 1, 1,
  183.  1, 1, 3, 3, 3, 3, 1, 1,
  184.  1, 1, 4, 4, 4, 4, 1, 1,
  185.  1, 1, 5, 6, 6, 5, 1, 1,
  186.  1, 1, 6, 7, 7, 6, 1, 1,
  187.  1, 1, 7, 8, 8, 7, 1, 1,
  188.  1, 1, 1, 1, 1, 1, 1, 1};
  189. #elif defined BLACKAG3
  190. /* Space positional bonus */
  191. static const short __aligned SpaceBonusB[64] =
  192. {0, 0, 0, 0, 0, 0, 0, 0,
  193.  0, 0, 2, 2, 2, 2, 0, 0,
  194.  0, 0, 3, 3, 3, 3, 0, 0,
  195.  0, 0, 4, 4, 4, 3, 0, 0,
  196.  0, 0, 6, 6, 4, 4, 0, 0,
  197.  0, 0, 7, 7, 5, 5, 0, 0,
  198.  0, 0, 8, 8, 7, 7, 0, 0,
  199.  0, 0, 0, 0, 0, 0, 0, 0};
  200. #elif defined BLACKAG4
  201. /* Space positional bonus */
  202. static const short __aligned SpaceBonusB[64] =
  203. {1, 1, 1, 1, 1, 1, 1, 1,
  204.  1, 1, 2, 4, 4, 2, 1, 1,
  205.  1, 1, 2, 4, 4, 2, 1, 1,
  206.  1, 1, 2, 4, 4, 2, 1, 1,
  207.  1, 1, 2, 4, 4, 2, 1, 1,
  208.  1, 1, 2, 4, 4, 2, 1, 1,
  209.  1, 1, 2, 4, 4, 2, 1, 1,
  210.  1, 1, 1, 1, 1, 1, 1, 1};
  211. #endif
  212.  
  213. #ifdef WHITEAG0
  214. /* Space positional bonus */
  215. static const short __alignedSpaceBonusW[64] =
  216. {0, 0, 0, 0, 0, 0, 0, 0,
  217.  0, 0, 5, 5, 5, 5, 0, 0,
  218.  0, 0, 3, 4, 4, 3, 0, 0,
  219.  0, 0, 2, 4, 4, 2, 0, 0,
  220.  0, 0, 1, 4, 4, 1, 0, 0,
  221.  0, 0, 1, 4, 4, 1, 0, 0,
  222.  0, 0, 1, 2, 2, 1, 0, 0,
  223.  0, 0, 0, 0, 0, 0, 0, 0};
  224. #elif defined WHITEAG1
  225. /* Space positional bonus */
  226. static const short __alignedSpaceBonusW[64] =
  227. {1, 1, 1, 1, 1, 1, 1, 1,
  228.  1, 1, 3, 7, 7, 3, 1, 1,
  229.  1, 1, 3, 6, 6, 3, 1, 1,
  230.  1, 1, 3, 5, 5, 3, 1, 1,
  231.  1, 1, 2, 4, 4, 2, 1, 1,
  232.  1, 1, 2, 3, 3, 2, 1, 1,
  233.  1, 1, 2, 2, 2, 2, 1, 1,
  234.  1, 1, 1, 1, 1, 1, 1, 1};
  235. #elif defined WHITEAG2
  236. /* Space positional bonus */
  237. static const short __alignedSpaceBonusW[64] =
  238. {1, 1, 1, 1, 1, 1, 1, 1,
  239.  1, 1, 7, 8, 8, 7, 1, 1,
  240.  1, 1, 6, 7, 7, 6, 1, 1,
  241.  1, 1, 5, 6, 6, 5, 1, 1,
  242.  1, 1, 4, 4, 4, 4, 1, 1,
  243.  1, 1, 3, 3, 3, 3, 1, 1,
  244.  1, 1, 2, 2, 2, 2, 1, 1,
  245.  1, 1, 1, 1, 1, 1, 1, 1};
  246. #elif defined WHITEAG3
  247. /* Space positional bonus */
  248. static const short __alignedSpaceBonusW[64] =
  249. {0, 0, 0, 0, 0, 0, 0, 0,
  250.  0, 0, 8, 8, 7, 7, 0, 0,
  251.  0, 0, 7, 7, 5, 5, 0, 0,
  252.  0, 0, 6, 6, 4, 4, 0, 0,
  253.  0, 0, 4, 4, 4, 3, 0, 0,
  254.  0, 0, 3, 3, 3, 3, 0, 0,
  255.  0, 0, 2, 2, 2, 2, 0, 0,
  256.  0, 0, 0, 0, 0, 0, 0, 0};
  257. #elif defined WHITEAG4
  258. /* Space positional bonus */
  259. static const short __alignedSpaceBonusW[64] =
  260. {1, 1, 1, 1, 1, 1, 1, 1,
  261.  1, 1, 2, 4, 4, 2, 1, 1,
  262.  1, 1, 2, 4, 4, 2, 1, 1,
  263.  1, 1, 2, 4, 4, 2, 1, 1,
  264.  1, 1, 2, 4, 4, 2, 1, 1,
  265.  1, 1, 2, 4, 4, 2, 1, 1,
  266.  1, 1, 2, 4, 4, 2, 1, 1,
  267.  1, 1, 1, 1, 1, 1, 1, 1};
  268. #endif
  269. #endif
  270.  
  271. short __aligned Mwpawn[64];
  272. short __aligned Mbpawn[64];
  273. short __aligned Mknight[2][64];
  274. short __aligned Mbishop[2][64];
  275. static short __aligned Mking[2][64];
  276. static short __aligned Kfield[2][64];
  277. static short __aligned c1, c2, *atk1, *atk2, *PC1, *PC2;
  278. static short __aligned atak[2][64];
  279. short __aligned emtl[2];
  280. static short __aligned PawnBonus, BishopBonus, RookBonus;
  281. static short __aligned KNIGHTPOST, KNIGHTSTRONG, BISHOPSTRONG, KATAK;
  282. static short __aligned PEDRNK2B, PWEAKH, PADVNCM, PADVNCI, PAWNSHIELD, PDOUBLED, PBLOK;
  283. static short __aligned RHOPN, RHOPNX, KHOPN, KHOPNX, KSFTY;
  284. static short __aligned ATAKD, HUNGP, HUNGX, KCASTLD, KMOVD, XRAY, PINVAL;
  285. short __aligned pscore[2];
  286. short __aligned tmtl;
  287.  
  288. #ifdef CACHE
  289. inline void
  290. PutInEETable (ARGSZ int side,int score)
  291.  
  292. /*
  293.  * Store the current eval position in the transposition table.
  294.  */
  295.  
  296. {
  297.     register struct etable *ptbl;
  298.     ptbl = &etab[side][hashkey % (ETABLE)];
  299. //    if (ptbl->ehashbd == hashbd) return;
  300.     ptbl->ehashbd = hashbd;
  301.     ptbl->escore[white] = pscore[white];
  302.     ptbl->escore[black] = pscore[black];
  303.     ptbl->hung[white] = hung[white];
  304.     ptbl->hung[black] = hung[black];
  305.     ptbl->score = score;
  306. #ifndef AMIGA
  307.     bcopy (svalue, &(ptbl->sscore), sizeof (svalue));
  308. #else
  309.     MoveMem128(svalue,&(ptbl->sscore));
  310.    /* MoveMem(svalue,&(ptbl->sscore),sizeof (svalue));*/
  311. #endif
  312. /*    bcopy (&(ptbl->sscore), svalue, sizeof (svalue)); */
  313. #if !defined CHESSTOOL && !defined XBOARD
  314.     EADD++;
  315. #endif
  316.     return;
  317. }
  318.  
  319. inline int
  320. CheckEETable (ARGSZ int side)
  321.  
  322. /* Get an evaluation from the transposition table */
  323. {
  324.     register struct etable *ptbl;
  325.     ptbl = &etab[side][hashkey % (ETABLE)];
  326.     if (hashbd == ptbl->ehashbd) return true;
  327.     return false;
  328. }
  329.  
  330. inline int
  331. ProbeEETable (short int side, short int *score)
  332.  
  333. /* Get an evaluation from the transposition table */
  334. {
  335.     register struct etable *ptbl;
  336.     ptbl = &etab[side][hashkey % (ETABLE)];
  337.     if (hashbd == ptbl->ehashbd)
  338.       {
  339.       pscore[white] = ptbl->escore[white];
  340.       pscore[black] = ptbl->escore[black];
  341. #ifndef AMIGA
  342.       bcopy (&(ptbl->sscore),svalue, sizeof (svalue));
  343. #else
  344.       MoveMem128(&(ptbl->sscore),svalue);
  345.      /* MoveMem (&(ptbl->sscore),svalue, sizeof (svalue));*/
  346. #endif
  347. /*      bcopy (svalue, &(ptbl->sscore), sizeof (svalue));*/
  348.       *score = ptbl->score;
  349.           hung[white] = ptbl->hung[white];
  350.           hung[black] = ptbl->hung[black];
  351. #if !defined CHESSTOOL && !defined XBOARD
  352.       EGET++;
  353. #endif
  354.       return true;
  355.       }
  356.     return false;
  357.  
  358. }
  359.  
  360. #endif
  361.  
  362.  
  363.  
  364. #ifndef PRE4PL67
  365.   short dist_ (short, short, short, short);
  366.   short kpkwv_ (short, short, short, short, short, short);
  367. /* ............    POSITIONAL EVALUATION ROUTINES    ............ */
  368.  
  369. /*
  370.  * Inputs are:
  371.  * pmtl[side] - value of pawns
  372.  * mtl[side]  - value of all material
  373.  * emtl[side] - vaule of all material - value of pawns - value of king
  374.  * hung[side] - count of hung pieces
  375.  * Tscore[ply] - search tree score for ply
  376.  * ply
  377.  * Pscore[ply] - positional score for ply ply
  378.  * INCscore    - bonus score or penalty for certain positions
  379.  * slk - single lone king flag
  380.  * Sdepth - search goal depth
  381.  * xwndw - evaluation window about alpha/beta
  382.  * EWNDW - second evaluation window about alpha/beta
  383.  * ChkFlag[ply]- checking piece at level ply or 0 if no check
  384.  * PC1[column] - # of my pawns in this column
  385.  * PC2[column] - # of opponents pawns in column
  386.  * PieceCnt[side] - just what it says
  387.  */
  388. inline
  389. int
  390. ScoreKPK (short side,
  391.       short winner,
  392.       short loser,
  393.       short king1,
  394.       register short king2,
  395.       register short sq)
  396.  
  397. /*
  398.  * Score King and Pawns versus King endings.
  399.  */
  400.  
  401. {
  402.     register short s, r;
  403.  
  404.     s = ((PieceCnt[winner] == 1) ? 50 : 120);
  405.     if (winner == white)
  406.       {
  407.       r = row (sq) - ((side == loser) ? 1 : 0);
  408.       if (row (king2) >= r && distance (sq, king2) < 8 - r)
  409.           s += 10 * row (sq);
  410.       else
  411.           s = 500 + 50 * row (sq);
  412.       if (row (sq) < 6)
  413.           sq += 16;
  414.       else if (row (sq) == 6)
  415.           sq += 8;
  416.       }
  417.     else
  418.       {
  419.       r = row (sq) + ((side == loser) ? 1 : 0);
  420.       if (row (king2) <= r && distance (sq, king2) < r + 1)
  421.           s += 10 * (7 - row (sq));
  422.       else
  423.           s = 500 + 50 * (7 - row (sq));
  424.       if (row (sq) > 1)
  425.           sq -= 16;
  426.       else if (row (sq) == 1)
  427.           sq -= 8;
  428.       }
  429.     s += 8 * (taxicab (king2, sq) - taxicab (king1, sq));
  430.     return (s);
  431. }
  432.  
  433. short 
  434. kpkwv_ (short pf, short pr, short wf, short wr, short bf, short br)
  435. {
  436.  
  437.   /*
  438.    *  Don Beal's routine, which was originally in Fortran.  See AICC 2
  439.    */
  440.  
  441.   static short wbdd, mbpf, nbpf, blpu;
  442.   short dist_ (short, short, short, short);
  443.   static short brpu, mwpf, wlpu, wrpu, blpuu, brpuu, wlpuu, wrpuu, md,
  444.     bq, blpuuu, brpuuu, bsd, tbf, sgf, bpp, sdr, sgr, wsd, wsg, ppr, wpp;
  445.  
  446.   ppr = ((pr == 2)?3:0);
  447.   if (pf == 1)
  448.   { if (bf == 3)
  449.     { if (pr == 7 && wf == 1 && wr == 8 && br > 6) return(0);
  450.       if (pr == 6 && wf < 4 && wr == 6 && br == 8) return(1);
  451.     }
  452.  
  453.     if (bf == 1 && br > pr) return(0);
  454.     if (pr == 7 && bf > 2) return(1);
  455.     if (bf <= 3 && br - ppr > 1) return(0);
  456.     if (wf == 1 && bf == 3 && wr - pr == 1 && br - pr == 1) return(0);
  457.   }
  458.   bq = dist_ (bf, br, pf, 8);
  459.   if (bq > 8 - ppr) return(1);
  460.   mbpf = bf - pf;
  461.   if (mbpf < 0) mbpf = -mbpf;
  462.   bpp = dist_ (bf, br, pf, ppr);
  463.   wpp = dist_ (wf, wr, pf, ppr);
  464.   if (bpp - wpp < -1 && br - pr != mbpf) return(0);
  465.   if (pf == 1 && pr <= 3 && wf <= 2 && wr == 8 && bf == 4 && br >= 7) return(1);
  466.   if (!(pf != 2 || pr != 6 || bf != 1 || br != 8))
  467.   { if (wf <= 3 && wr == 6) return(0);
  468.     if (wf == 4 && wr == 8) return(0);
  469.   }
  470.   if (pr == 7)
  471.   { if (wr < 8 && wpp == 2 && bq == 0) return(1);
  472.     if (wr == 6 && wf == pf && bq == 0) return(1);
  473.     if (wr >= 6 && wpp <= 2 && bq != 0) return(1);
  474.   }
  475.   blpuu = dist_ (bf, br, pf - 1, pr + 2);
  476.   wbdd = dist_ (wf, wr, bf, br - 2);
  477.   brpuu = dist_ (bf, br, pf + 1, pr + 2);
  478.   if (pr == 6)
  479.   { if (dist_ (bf, br, pf + 1, pr) > 1 &&
  480.         brpuu > dist_ (wf, wr, pf + 1, pr)) return(1);
  481.     if (pf != 1)
  482.     { if (blpuu > dist_ (wf, wr, pf - 1, pr)) return(1);
  483.       if (br == 8 && mbpf == 1 && wbdd == 1) return(1);
  484.       if (br > 6 && nbpf == 2 && dist_ (wf, wr, bf, 5) <= 1) return(1);
  485.     }
  486.     else
  487.       if (wf == 1 && wr == 8 && bf == 2 && br == 6) return(0);
  488.   }
  489.   mwpf = wf - pf;
  490.   if (mwpf < 0) mwpf = -mwpf;
  491.   if (pr >= 5 && mwpf == 2 && wr == pr && bf == wf && br - pr == 2) return(1);
  492.   brpu = dist_ (bf, br, pf + 1, pr + 1);
  493.   wrpu = dist_ (wf, wr, pf + 1, pr + 1);
  494.   blpu = dist_ (bf, br, pf - 1, pr + 1);
  495.   wlpu = dist_ (wf, wr, pf - 1, pr + 1);
  496.   if (!(pf == 1 || pr != 5))
  497.   { if (mwpf <= 1 && wr - pr == 1) return(1);
  498.     if (wrpu == 1 && brpu > 1) return(1);
  499.     if (wr >= 4 && bf == wf && br - pr >= 2 && mbpf == 3) return(1);
  500.     if (wlpu == 1 && blpu > 1) return(1);
  501.   }
  502.   if (pr == 2 && br == 3 && mbpf > 1 && dist_ (wf, wr, bf, br + 2) <= 1) return(1);
  503.   if (wr - pr == 2 && br == pr && mbpf == 1 && mwpf > 1 &&
  504.       (wf - pf) * (bf - pf) > 0) return(0);
  505.   if (pf == 1 && wf == 1 && wr == br && bf > 3) return(1);
  506.   sgf = pf - 1;
  507.   if (wf >= pf) { sgf = pf + 1; }
  508.   sgr = wr - (mwpf - 1);
  509.   if (mwpf == 0 && wr > br) sgr = wr - 1;
  510.   wsg = dist_ (wf, wr, sgf, sgr);
  511.   if (wr - pr - mwpf > 0 && wr - br >= -1 && bpp - (wsg + (sgr - ppr))
  512.       >= -1 && dist_ (bf, br, sgf, sgr) > wsg) return(1);
  513.   md = mbpf - mwpf;
  514.   if (!(pf != 1 || bf <= 3))
  515.   { sdr = br + (bf - 3);
  516.     if (sdr > 8) sdr = 8;
  517.     if (wr > br + 1) sdr = br;
  518.     if (sdr > ppr)
  519.     { wsd = dist_ (wf, wr, 3, sdr);
  520.       bsd = dist_ (bf, br, 3, sdr);
  521.       if (bsd - wsd < -1) return(0);
  522.       if (bsd <= wsd && md <= 0) return(0);
  523.     }
  524.   }
  525.   brpuuu = dist_ (bf, br, pf + 1, pr + 3);
  526.   if (brpu > wrpu && brpuuu > wrpu && pr - wr != pf - wf) return(1);
  527.   if (brpuuu == 0 && wrpu == 1) return(1);
  528.   blpuuu = dist_ (bf, br, pf - 1, pr + 3);
  529.   if (pf != 1)
  530.   { if (blpu > wlpu && blpuuu > wlpu && pr - wr != wf - pf) return(1);
  531.     if (blpuuu == 0 && wlpu == 1) return(1);
  532.   }
  533.   wrpuu = dist_ (wf, wr, pf + 1, pr + 2);
  534.   if (brpuu > wrpuu) return(1);
  535.   wlpuu = dist_ (wf, wr, pf - 1, pr + 2);
  536.   if (pf > 1 && blpuu > wlpuu) return(1);
  537.   if (br == pr)
  538.   { if (mwpf <= 2 && wr - pr == -1 && mbpf != 2) return(1);
  539.     if (dist_ (wf, wr, bf - 1, br + 2) <= 1 && bf - pf > 1) return(1);
  540.     if (dist_ (wf, wr, bf + 1, br + 2) <= 1 && bf - pf < -1) return(1);
  541.   }
  542.   if (pf != 1)
  543.   { if (br == pr && mbpf > 1 && dist_ (wf, wr, pf, pr - 1) <= 1) return(1);
  544.     if (br - pr >= 3 && wbdd == 1) return(1);
  545.     if (wr - pr >= 2 && wr < br && md >= 0) return(1);
  546.     if (mwpf <= 2 && wr - pr >= 3 && bf != pf && wr - br <= 1) return(1);
  547.     if (wr >= pr && br - pr >= 5 && mbpf >= 3 && md >= -1 && ppr == 3) return(1);
  548.     if (md >= -1 && pr == 2 && br == 8) return(1);
  549.   }
  550.   tbf = bf - 1;
  551.   if (pf > bf) tbf = bf + 1;
  552.   if (mbpf > 1 && br == ppr && dist_ (wf, wr, tbf, wr + 2) <= 1) return(1);
  553.   if (br == pr && bf - pf == -2 && dist_ (wf, wr, pf + 2, pr - 1) <= 1) return(1);
  554.   if (pf > 2 && br == pr && bf - pf == 2 &&
  555.       dist_ (wf, wr, pf - 2, pr - 1) <= 1) return(1);
  556.   return(0);
  557. }                /* kpkwv_ */
  558.  
  559. short 
  560. kpkbv_ (short pf, short pr, short wf, short wr, short bf, short br)
  561. {
  562.   static short incf[8] =
  563.     {0, 1, 1, 1, 0, -1, -1, -1};
  564.   static short incr[8] =
  565.     {1, 1, 0, -1, -1, -1, 0, 1};
  566.  
  567.   short dist_ (short, short, short, short);
  568.   short kpkwv_ (short, short, short, short, short, short);
  569.   static short i, nm, nbf, nbr;
  570.  
  571.   nm = 0;
  572.   for (i = 0; i < 8; ++i)
  573.     {
  574.       nbf = bf + incf[i];
  575.       if (nbf < 1 || nbf > 8) continue;
  576.       nbr = br + incr[i];
  577.       if (nbr < 1 || nbr > 8) continue;
  578.       if (dist_ (nbf, nbr, wf, wr) < 2) continue;
  579.       if (nbf == pf && nbr == pr) return(0);
  580.       if (nbr == pr + 1 && (nbf == pf - 1 || nbf == pf + 1)) continue;
  581.       ++nm;
  582.       if (kpkwv_ (pf, pr, wf, wr, nbf, nbr) == 0) return(0);
  583.     }
  584.   if (nm > 0) return(-1);
  585.   return(0);
  586. }                /* kpkbv_ */
  587.  
  588. short 
  589. dist_ (short f1, short r1, short f2, short r2)
  590. {
  591.   short ts;
  592.   static short fd, rd;
  593.  
  594.   fd = f2 - f1;
  595.   if (fd < 0) fd = -fd;
  596.  
  597.   rd = r2 - r1;
  598.   if (rd < 0) rd = -rd;
  599.  
  600.  ts = ((rd > fd) ? rd : fd);
  601.  return(ts);
  602. }                /* dist_ */
  603.  
  604. inline
  605. int
  606. ScoreK1PK (short side,
  607.        short winner,
  608.        short loser,
  609.        short king1,
  610.        register short king2,
  611.        register short sq)
  612.  
  613.      /*
  614.       *  We call Don Beal's routine with the necessary parameters and determine
  615.       *  win/draw/loss.  Then we compute the real evaluation which is +-500 for
  616.       *  a win/loss and 10 for a draw, plus some points to lead the computer to
  617.       *  a decisive winning/drawing line.
  618.       */
  619.  
  620. {
  621.   short win, sqc, sqr, k1c, k1r, k2c, k2r;
  622.   const int drawn = 10, won = 500;
  623.  
  624.   sqc = column (sq) + 1;
  625.   sqr = row (sq) + 1;
  626.   k1c = column (king1) + 1;
  627.   k1r = row (king1) + 1;
  628.   k2c = column (king2) + 1;
  629.   k2r = row (king2) + 1;
  630.   if (winner == black)
  631.     {
  632.       sqr = 9 - sqr;
  633.       k1r = 9 - k1r;
  634.       k2r = 9 - k2r;
  635.     }
  636.   if (sqc > 4)
  637.     {
  638.       sqc = 9 - sqc;
  639.       k1c = 9 - k1c;
  640.       k2c = 9 - k2c;
  641.     }
  642.  
  643.   if (side == winner)
  644.     win = kpkwv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  645.   else
  646.     win = kpkbv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  647.  
  648.   if (!win)
  649.     return drawn + 5 * distance (sq, king2);
  650.   else
  651.     return won + 50 * (sqr - 2);
  652.  
  653. }
  654.  
  655.  
  656. inline
  657. int
  658. ScoreKBNK (short winner, short king1, short king2)
  659.  
  660.  
  661. /*
  662.  * Score King+Bishop+Knight versus King endings.  Works fine now.
  663.  */
  664.  
  665. {
  666.     register short s, Bsq, Nsq, KBNKsq = 0;
  667.  
  668.     if (board[PieceList[winner][1]] == bishop)
  669.       {
  670.         Bsq = PieceList[winner][1];
  671.         Nsq = PieceList[winner][2];
  672.       }
  673.     else
  674.       {
  675.         Bsq = PieceList[winner][2];
  676.         Nsq = PieceList[winner][1];
  677.       }
  678.  
  679.     KBNKsq = (((row (Bsq) % 2) == (column (Bsq) % 2)) ? 0 : 7);
  680.  
  681.     s = emtl[winner] - 300;
  682.     s += ((KBNKsq == 0) ? KBNK[king2] : KBNK[locn (row (king2), 7 - column (king2))]);
  683.  
  684. //  The following 2 lines are a fix for this version
  685.    s -= (8*taxicab(king1,king2) + 2*distance(Nsq,king2) + 
  686.                                     distance(Bsq,king2)); 
  687.    s += KingEnding[king1];
  688.     return (s);
  689. }
  690.  
  691. #ifdef notdef
  692.  
  693. inline
  694. int
  695. ScoreKBNK (short winner, short king1, short king2)
  696.  
  697.  
  698. /*
  699.  * Score King+Bishop+Knight versus King endings. This doesn't work all that
  700.  * well but it's better than nothing.
  701.  */
  702.  
  703. {
  704.     register short s, sq, KBNKsq = 0;
  705.  
  706.     for (sq = 0; sq < 64; sq++)
  707.     if (board[sq] == bishop)
  708.         KBNKsq = (((row (sq) % 2) == (column (sq) % 2)) ? 0 : 7);
  709.  
  710.     s = emtl[winner] - 300;
  711.     s += ((KBNKsq == 0) ? KBNK[king2] : KBNK[locn (row (king2), 7 - column (king2))]);
  712.     s -= ((taxicab (king1, king2) + distance (PieceList[winner][1], king2) + distance (PieceList[winner][2], king2)));
  713.     return (s);
  714. }
  715. #endif
  716.  
  717. inline
  718. short
  719. ScoreLoneKing (short side)
  720.  
  721.      /*
  722.       * Static evaluation when loser has only a king and winner has no pawns or no
  723.       * pieces.
  724.       */
  725.  
  726. {
  727. //  short ts;
  728.   register short winner, loser, king1, king2, s, i;
  729.  
  730.   if (mtl[white] == valueK && mtl[black] == valueK)
  731.     return 0;
  732.   UpdateWeights ();
  733.   winner = ((mtl[white] > mtl[black]) ? white : black);
  734.   loser = winner ^ 1;
  735.   king1 = PieceList[winner][0];
  736.   king2 = PieceList[loser][0];
  737.  
  738.   s = 0;
  739.  
  740.   if (pmtl[winner] == 0)
  741.     {
  742.       if (emtl[winner] == valueB + valueN)
  743.     s = ScoreKBNK (winner, king1, king2);
  744.       else if (emtl[winner] == valueN + valueN)
  745.     s = 0;
  746.     else if (emtl[winner] < valueR)
  747.        s = 0;
  748.       else
  749.     s = 500 + emtl[winner] - DyingKing[king2] - 2 * distance (king1, king2);
  750.     }
  751.   else
  752.     {
  753.       if (pmtl[winner] == valueP)
  754.     s = ScoreK1PK (side, winner, loser, king1, king2, PieceList[winner][1]);
  755.       else
  756.     for (i = 1; i <= PieceCnt[winner]; i++)
  757.       s += ScoreKPK (side, winner, loser, king1, king2, PieceList[winner][i]);
  758.     }
  759.   if (side != winner)
  760.     s = 0 - s;
  761.   return(s);
  762. //  ts = ((side == winner) ? s : -s);
  763. //  return (ts);
  764. }
  765.  
  766.  
  767. int
  768. evaluate (register short side,
  769.       register short ply,
  770.       register short depth,
  771.           register short ext,
  772.       register short alpha,
  773.       register short beta,
  774.       short INCscore,
  775.       short *InChk)    /* output Check flag */
  776.  
  777. /*
  778.  * Compute an estimate of the score by adding the positional score from the
  779.  * previous ply to the material difference. If this score falls inside a
  780.  * window which is 180 points wider than the alpha-beta window (or within a
  781.  * 50 point window during quiescence search) call ScorePosition() to
  782.  * determine a score, otherwise return the estimated score. If one side has
  783.  * only a king and the other either has no pawns or no pieces then the
  784.  * function ScoreLoneKing() is called.
  785.  */
  786.  
  787. {
  788.     register short xside;
  789.     register short slk;
  790.     short s;
  791.  
  792.     xside = side ^ 1;
  793.     s = -Pscore[ply - 1] + mtl[side] - mtl[xside] - INCscore;
  794.     hung[white] = hung[black] = 0;
  795.     slk = ((mtl[white] == valueK && (pmtl[black] == 0 || emtl[black] == 0)) ||
  796.       (mtl[black] == valueK && (pmtl[white] == 0 || emtl[white] == 0)));
  797.  
  798.           /* should we use the estimete or score the position */
  799.     if ( !slk && (ply == 1 ||
  800. #ifdef CACHE
  801.         (CheckEETable (side)) ||
  802. #endif
  803.         (myneweval ? ((
  804.         (ply==Sdepth || (!ext && depth == 0 && s>=alpha-30 && s<=beta+30)) ||
  805.         (ext && (s >= (alpha - 30) && s <= (beta + 30)) )) )
  806.         :
  807.         ((Sdepth ==  ply) ||
  808.         (ply > Sdepth && (s >= (alpha - 30) && s <= (beta + 30)) )) )
  809.         ))
  810.  
  811.       {
  812.       /* score the position */
  813.       ataks (side, atak[side]);
  814.       if (Anyatak (side, PieceList[xside][0])){
  815.       ataks (xside, atak[xside]);
  816.       ChkFlag[ply-1] = *InChk = Anyatak (xside, PieceList[side][0]);
  817.           return (10001 - ply);
  818.       }
  819.       ataks (xside, atak[xside]);
  820.       ChkFlag[ply-1] = *InChk = Anyatak (xside, PieceList[side][0]);
  821.  
  822. #ifndef BAREBONES 
  823.       EvalNodes++;
  824. #endif
  825.     if(ply>4)PUTVAR=true;
  826.           s = ScorePosition (side);
  827.     PUTVAR=false;
  828.       }
  829.     else
  830.       {
  831.       /* use the estimate but look at check and slk */
  832.        *InChk = SqAtakd (PieceList[side][0], xside);
  833.        ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] + 1 : 0);
  834.        if (SqAtakd (PieceList[xside][0], side)){ return (10001 - ply); }
  835. #ifdef DEBUG 
  836.        if(debuglevel & 4096){
  837.       printf("%lx %lx %d %d\n",hashbd,hashkey,ply,s);
  838.       }
  839. #endif
  840.       if (slk){
  841.         if(ply>4)PUTVAR=true;
  842.               s = ScoreLoneKing (side);
  843.         PUTVAR=false;}
  844.       }
  845.  
  846.     Pscore[ply] = s - mtl[side] + mtl[xside];
  847.     ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] + 1 : 0);
  848.     QueenCheck[ply - 1] =       /* tom@izf.tno.nl */
  849.           ((*InChk) && board[TOsquare] == queen) ? TOsquare : 0;
  850. #ifdef DEBUG 
  851.        if(debuglevel & 4096){
  852.     printf("%lx %lx %d %d\n",hashbd,hashkey,ply,s);
  853.     }
  854. #endif
  855.     return (s);
  856. }
  857.  
  858. inline
  859. int
  860. BRscan (register short sq, short *mob)
  861.  
  862. /*
  863.  * Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the
  864.  * hung[] array if a pin is found.
  865.  */
  866. {
  867.     register unsigned char *ppos, *pdir;
  868.     register short s, mobx;
  869.     register short u, pin;
  870.     short piece, *Kf;
  871.     mobx = s = 0;
  872.     Kf = Kfield[c1];
  873.     piece = board[sq];
  874.     ppos = nextpos[piece][sq];
  875.     pdir = nextdir[piece][sq];
  876.     u = ppos[sq];
  877.     pin = -1;            /* start new direction */
  878.     do
  879.       {
  880.       s += Kf[u];
  881.       if (color[u] == neutral)
  882.         {
  883.         mobx++;
  884.         if (ppos[u] == pdir[u])
  885.             pin = -1;    /* oops new direction */
  886.         u = ppos[u];
  887.         }
  888.       else if (pin < 0)
  889.         {
  890.         if (board[u] == pawn || board[u] == king)
  891.             u = pdir[u];
  892.         else
  893.           {
  894.               if (ppos[u] != pdir[u])
  895.               pin = u;    /* not on the edge and on to find a pin */
  896.               u = ppos[u];
  897.           }
  898.         }
  899.       else
  900.         {
  901.         if (color[u] == c2 && (board[u] > piece || atk2[u] == 0))
  902.           {
  903.               if (color[pin] == c2)
  904.             {
  905.                 s += PINVAL;
  906.                 if (atk2[pin] == 0 || atk1[pin] > control[board[pin]] + 1)
  907.                 ++hung[c2];
  908.             }
  909.               else
  910.               s += XRAY;
  911.           }
  912.         pin = -1;    /* new direction */
  913.         u = pdir[u];
  914.         }
  915.       }
  916.     while (u != sq);
  917.     *mob = mobx;
  918.     return s;
  919. }
  920.  
  921. inline
  922. short
  923. KingScan (register short sq)
  924.  
  925. /*
  926.  * Assign penalties if king can be threatened by checks, if squares near the
  927.  * king are controlled by the enemy (especially the queen), or if there are
  928.  * no pawns near the king. 
  929.     The following must be true: 
  930.         board[sq] == king 
  931.         c1 == color[sq] 
  932.         c2 == otherside[c1]
  933.  */
  934.  
  935. #define ScoreThreat \
  936.     if (color[u] != c2)\
  937.       if (atk1[u] == 0 || (atk2[u] & 0xFF) > 1) ++cnt;\
  938.       else s -= 3
  939.  
  940. {
  941.     register short cnt;
  942.     register unsigned char *ppos, *pdir;
  943.     register short s;
  944.     register short u;
  945.     short ok;
  946.  
  947.     s = 0;
  948.     cnt = 0;
  949.     if (HasBishop[c2] || HasQueen[c2])
  950.       {
  951.       ppos = nextpos[bishop][sq];
  952.       pdir = nextdir[bishop][sq];
  953.       u = ppos[sq];
  954.       do
  955.         {
  956.         if (atk2[u] & ctlBQ)
  957.             ScoreThreat;
  958.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  959.         }
  960.       while (u != sq);
  961.       }
  962.     if (HasRook[c2] || HasQueen[c2])
  963.       {
  964.       ppos = nextpos[rook][sq];
  965.       pdir = nextdir[rook][sq];
  966.       u = ppos[sq];
  967.       do
  968.         {
  969.         if (atk2[u] & ctlRQ)
  970.             ScoreThreat;
  971.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  972.         }
  973.       while (u != sq);
  974.       }
  975.     if (HasKnight[c2])
  976.       {
  977.       pdir = nextdir[knight][sq];
  978.       u = pdir[sq];
  979.       do
  980.         {
  981.         if (atk2[u] & ctlNN)
  982.             ScoreThreat;
  983.         u = pdir[u];
  984.         }
  985.       while (u != sq);
  986.       }
  987.     s += (KSFTY * KTHRT[cnt]) / 16;
  988.  
  989.     cnt = 0;
  990.     ok = false;
  991.     pdir = nextpos[king][sq];
  992.     u = pdir[sq];
  993.     do
  994.       {
  995.       if (board[u] == pawn)
  996.           ok = true;
  997.       if (atk2[u] > atk1[u])
  998.         {
  999.         ++cnt;
  1000.         if (atk2[u] & ctlQ)
  1001.             if (atk2[u] > ctlQ + 1 && atk1[u] < ctlQ)
  1002.             s -= 4 * KSFTY;
  1003.         }
  1004.       u = pdir[u];
  1005.       }
  1006.     while (u != sq);
  1007.     if (!ok)
  1008.     s -= KSFTY;
  1009.     if (cnt > 1)
  1010.     s -= (KSFTY);
  1011.     return (s);
  1012. }
  1013.  
  1014. inline
  1015. int
  1016. trapped (register short sq)
  1017.  
  1018. /*
  1019.  * See if the attacked piece has unattacked squares to move to. The following
  1020.  * must be true: c1 == color[sq] c2 == otherside[c1]
  1021.  */
  1022.  
  1023. {
  1024.     register short u;
  1025.     register unsigned char *ppos, *pdir;
  1026.     register short piece;
  1027.  
  1028.     piece = board[sq];
  1029.     ppos = nextpos[ptype[c1][piece]][sq];
  1030.     pdir = nextdir[ptype[c1][piece]][sq];
  1031.     if (piece == pawn)
  1032.       {
  1033.       u = ppos[sq];        /* follow no captures thread */
  1034.       if (color[u] == neutral)
  1035.         {
  1036.         if (atk1[u] >= atk2[u])
  1037.             return (false);
  1038.         if (atk2[u] < ctlP)
  1039.           {
  1040.               u = ppos[u];
  1041.               if (color[u] == neutral && atk1[u] >= atk2[u])
  1042.               return (false);
  1043.           }
  1044.         }
  1045.       u = pdir[sq];        /* follow captures thread */
  1046.       if (color[u] == c2)
  1047.           return (false);
  1048.       u = pdir[u];
  1049.       if (color[u] == c2)
  1050.           return (false);
  1051.       }
  1052.     else
  1053.       {
  1054.       u = ppos[sq];
  1055.       do
  1056.         {
  1057.         if (color[u] != c1)
  1058.             if (atk2[u] == 0 || board[u] >= piece)
  1059.             return (false);
  1060.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  1061.         }
  1062.       while (u != sq);
  1063.       }
  1064.     return (true);
  1065. }
  1066.  
  1067.  
  1068. static inline int
  1069. PawnValue (register short sq, short side)
  1070. /*
  1071.  * Calculate the positional value for a pawn on 'sq'.
  1072.  */
  1073.  
  1074. {
  1075.     register short fyle, rank;
  1076.     register short j, s, a1, a2, in_square, r, e;
  1077.  
  1078.     a1 = (atk1[sq] & 0x4FFF);
  1079.     a2 = (atk2[sq] & 0x4FFF);
  1080.     rank = row (sq);
  1081.     fyle = column (sq);
  1082.     s = 0;
  1083.     if (c1 == white)
  1084.       {
  1085.       s = Mwpawn[sq];
  1086.       if ((sq == 11 && color[19] != neutral) || (sq == 12 && color[20] != neutral)) s += PEDRNK2B;
  1087.       if ((fyle == 0 || PC1[fyle - 1] == 0) && (fyle == 7 || PC1[fyle + 1] == 0)) s += ISOLANI[fyle];
  1088.       else if (PC1[fyle] > 1) s += PDOUBLED;
  1089.  
  1090.       if (a1 < ctlP && atk1[sq + 8] < ctlP)
  1091.         {
  1092.         s += BACKWARD[a2 & 0xFF];
  1093.         if (PC2[fyle] == 0) s += PWEAKH;
  1094.         if (color[sq + 8] != neutral) s += PBLOK;
  1095.         }
  1096.       if(rank != 7 && color[sq+8] == black && board[sq+8] == pawn) s -= PCRASH;
  1097.       if (PC2[fyle] == 0)
  1098.         {
  1099.         r = rank - (side == black)?1:0;
  1100.         in_square = (row (bking) >= r && distance (sq, bking) < 8 - r);
  1101.         e = (a2 == 0 || side == white)? 0:1;
  1102.         for (j = sq + 8; j < 64; j += 8)
  1103.             if (atk2[j] >= ctlP) { e = 2; break; }
  1104.             else if (atk2[j] > 0 || color[j] != neutral) e = 1;
  1105.  
  1106.         if (e == 2) s += (stage * PassedPawn3[rank]) / 10;
  1107.         else if (in_square || e == 1) s += (stage * PassedPawn2[rank]) / 10;
  1108.         else if (emtl[black] > 0) s += (stage * PassedPawn1[rank]) / 10;
  1109.         else s += PassedPawn0[rank];
  1110.         }
  1111.       }
  1112.     else if (c1 == black)
  1113.       {
  1114.       s = Mbpawn[sq];
  1115.       if ((sq == 51 && color[43] != neutral) || (sq == 52 && color[44] != neutral)) s += PEDRNK2B;
  1116.  
  1117.       if ((fyle == 0 || PC1[fyle - 1] == 0) && (fyle == 7 || PC1[fyle + 1] == 0)) s += ISOLANI[fyle];
  1118.       else if (PC1[fyle] > 1) s += PDOUBLED;
  1119.  
  1120.       if (a1 < ctlP && atk1[sq - 8] < ctlP)
  1121.         {
  1122.         s += BACKWARD[a2 & 0xFF];
  1123.         if (PC2[fyle] == 0) s += PWEAKH;
  1124.         if (color[sq - 8] != neutral) s += PBLOK;
  1125.         }
  1126.       if(rank != 0 && color[sq+8] == white && board[sq+8] == pawn) s -= PCRASH;
  1127.       if (PC2[fyle] == 0)
  1128.         {
  1129.         r = rank + (side == white)?1:0;
  1130.         in_square = (row (wking) <= r && distance (sq, wking) < r + 1);
  1131.         e = (a2 == 0 || side == black)?0:1;
  1132.         for (j = sq - 8; j >= 0; j -= 8)
  1133.             if (atk2[j] >= ctlP) { e = 2; break; }
  1134.             else if (atk2[j] > 0 || color[j] != neutral) e = 1;
  1135.  
  1136.         if (e == 2) s += (stage * PassedPawn3[7 - rank]) / 10;
  1137.         else if (in_square || e == 1) s += (stage * PassedPawn2[7 - rank]) / 10;
  1138.         else if (emtl[white] > 0) s += (stage * PassedPawn1[7 - rank]) / 10;
  1139.         else s += PassedPawn0[7 - rank];
  1140.         }
  1141.       }
  1142.     if((rank >2 && rank < 6) && (fyle > 2 && fyle < 5)) s += PCENTER;
  1143.     if (a2 > 0)
  1144.       {
  1145.       if (a1 == 0 || a2 > ctlP + 1)
  1146.         {
  1147.         s += HUNGP;
  1148.         if (trapped (sq)) hung[c1] += 2;
  1149.         hung[c1]++;
  1150.         }
  1151.       else if (a2 > a1) s += ATAKD;
  1152.       }
  1153.     return (s);
  1154. }
  1155.  
  1156. inline
  1157. int
  1158. KnightValue (register short sq, short side)
  1159.  
  1160. /*
  1161.  * Calculate the positional value for a knight on 'sq'.
  1162.  */
  1163.  
  1164. {
  1165.     register short s, a2, a1;
  1166.  
  1167.     s = Mknight[c1][sq];
  1168.     a2 = (atk2[sq] & 0x4FFF);
  1169.     if (a2 > 0)
  1170.       {
  1171.       a1 = (atk1[sq] & 0x4FFF);
  1172.       if (a1 == 0 || a2 > ctlBN + 1)
  1173.         {
  1174.         s += HUNGP;
  1175.         if (trapped (sq))
  1176.             hung[c1] += 2;
  1177.         hung[c1]++;
  1178.         }
  1179.       else if (a2 >= ctlBN || a1 < ctlP)
  1180.           s += ATAKD;
  1181.       }
  1182.     return (s);
  1183. }
  1184.  
  1185. inline
  1186. int
  1187. BishopValue (register short sq, short side)
  1188.  
  1189. /*
  1190.  * Calculate the positional value for a bishop on 'sq'.
  1191.  */
  1192.  
  1193. {
  1194.     register short s;
  1195.     register short a2, a1;
  1196.     short mob;
  1197.  
  1198.     s = Mbishop[c1][sq];
  1199.     s += BRscan (sq, &mob);
  1200.     s += BMBLTY[mob];
  1201.     a2 = (atk2[sq] & 0x4FFF);
  1202.     if (a2 > 0)
  1203.       {
  1204.       a1 = (atk1[sq] & 0x4FFF);
  1205.       if (a1 == 0 || a2 > ctlBN + 1)
  1206.         {
  1207.         s += HUNGP;
  1208.         if (trapped (sq))
  1209.             hung[c1] += 2;
  1210.         hung[c1]++;
  1211.         }
  1212.       else if (a2 >= ctlBN || a1 < ctlP)
  1213.           s += ATAKD;
  1214.       }
  1215.     return (s);
  1216. }
  1217.  
  1218. inline
  1219. int
  1220. RookValue (register short sq, short side)
  1221.  
  1222. /*
  1223.  * Calculate the positional value for a rook on 'sq'.
  1224.  */
  1225.  
  1226. {
  1227.     register short s;
  1228.     register short fyle, a2, a1;
  1229.     short mob;
  1230.  
  1231.     s = RookBonus;
  1232.     s += BRscan (sq, &mob);
  1233.     s += RMBLTY[mob];
  1234.     fyle = column (sq);
  1235.     if (PC1[fyle] == 0)
  1236.     { s += RHOPN;
  1237.             if (PC2[fyle] == 0)
  1238.             s += RHOPNX;
  1239.         }
  1240.     if (pmtl[c2] > 100 && row (sq) == rank7[c1])
  1241.     s += 10;
  1242.     if (stage > 2)
  1243.     s += 14 - taxicab (sq, EnemyKing);
  1244.     a2 = (atk2[sq] & 0x4FFF);
  1245.     if (a2 > 0)
  1246.       {
  1247.       a1 = (atk1[sq] & 0x4FFF);
  1248.       if (a1 == 0 || a2 > ctlR + 1)
  1249.         {
  1250.         s += HUNGP;
  1251.         if (trapped (sq))
  1252.             hung[c1] += 2;
  1253.         hung[c1]++;
  1254.         }
  1255.       else if (a2 >= ctlR || a1 < ctlP)
  1256.           s += ATAKD;
  1257.       }
  1258.     return (s);
  1259. }
  1260.  
  1261. inline
  1262. int
  1263. QueenValue (register short sq, short side)
  1264.  
  1265. /*
  1266.  * Calculate the positional value for a queen on 'sq'.
  1267.  */
  1268.  
  1269. {
  1270.     register short s, a2, a1;
  1271.  
  1272.     s = ((distance (sq, EnemyKing) < 3) ? 12 : 0);
  1273.     if (stage > 2)
  1274.     s += 14 - taxicab (sq, EnemyKing);
  1275.     a2 = (atk2[sq] & 0x4FFF);
  1276.     if (a2 > 0)
  1277.       {
  1278.       a1 = (atk1[sq] & 0x4FFF);
  1279.       if (a1 == 0 || a2 > ctlQ + 1)
  1280.         {
  1281.         s += HUNGP;
  1282.         if (trapped (sq))
  1283.             hung[c1] += 2;
  1284.         hung[c1]++;
  1285.         }
  1286.       else if (a2 >= ctlQ || a1 < ctlP)
  1287.           s += ATAKD;
  1288.       }
  1289.     return (s);
  1290. }
  1291.  
  1292. inline
  1293. int
  1294. KingValue (register short sq, short side)
  1295.  
  1296. /*
  1297.  * Calculate the positional value for a king on 'sq'.
  1298.  */
  1299.  
  1300. {
  1301.     register short s;
  1302.     register short fyle;
  1303.     short a2, a1;
  1304.     s = (emtl[side ^ 1] > KINGPOSLIMIT) ? Mking[c1][sq] : Mking[c1][sq] / 2;
  1305.     if (KSFTY > 0)
  1306.     if (Developed[c2] || stage > 0)
  1307.         s += KingScan (sq);
  1308.     if (castld[c1])
  1309.     s += KCASTLD;
  1310.     else if (Mvboard[kingP[c1]])
  1311.     s += KMOVD;
  1312.  
  1313.     fyle = column (sq);
  1314.     if (PC1[fyle] == 0)
  1315.     s += KHOPN;
  1316.     if (PC2[fyle] == 0)
  1317.     s += KHOPNX;
  1318.     switch (fyle)
  1319.       {
  1320.       case 5:
  1321.       if (PC1[7] == 0)
  1322.           s += KHOPN;
  1323.       if (PC2[7] == 0)
  1324.           s += KHOPNX;
  1325.       /* Fall through */
  1326.       case 4:
  1327.       case 6:
  1328.       case 0:
  1329.       if (PC1[fyle + 1] == 0)
  1330.           s += KHOPN;
  1331.       if (PC2[fyle + 1] == 0)
  1332.           s += KHOPNX;
  1333.       break;
  1334.       case 2:
  1335.       if (PC1[0] == 0)
  1336.           s += KHOPN;
  1337.       if (PC2[0] == 0)
  1338.           s += KHOPNX;
  1339.       /* Fall through */
  1340.       case 3:
  1341.       case 1:
  1342.       case 7:
  1343.       if (PC1[fyle - 1] == 0)
  1344.           s += KHOPN;
  1345.       if (PC2[fyle - 1] == 0)
  1346.           s += KHOPNX;
  1347.       break;
  1348.       default:
  1349.       /* Impossible! */
  1350.       break;
  1351.       }
  1352.  
  1353.     a2 = (atk2[sq] & 0x4FFF);
  1354.     if (a2 > 0)
  1355.       {
  1356.       a1 = (atk1[sq] & 0x4FFF);
  1357.       if (a1 == 0 || a2 > ctlK + 1)
  1358.         {
  1359.         s += HUNGP;
  1360.         ++hung[c1];
  1361.         }
  1362.       else
  1363.           s += ATAKD;
  1364.       }
  1365.     return (s);
  1366. }
  1367.  
  1368.  
  1369.  
  1370.  
  1371. short
  1372. ScorePosition (register short side)
  1373.  
  1374. /*
  1375.  * Perform normal static evaluation of board position. A score is generated
  1376.  * for each piece and these are summed to get a score for each side.
  1377.  */
  1378.  
  1379. {
  1380.     register short score;
  1381.     register short sq, i, xside;
  1382.     short s;
  1383.  
  1384.     UpdateWeights ();
  1385.     xside = side ^ 1;
  1386.     hung[white] = hung[black] = pscore[white] = pscore[black] = 0;
  1387. #ifdef CACHE
  1388.     if (!(hashkey+hashbd) || !ProbeEETable (side, &s))
  1389.       {
  1390. #endif
  1391.       for (c1 = white; c1 <= black; c1++)
  1392.         {
  1393.         c2 = c1 ^ 1;
  1394.         /* atk1 is array of atacks on squares by my side */
  1395.         atk1 = atak[c1];
  1396.         /* atk2 is array of atacks on squares by other side */
  1397.         atk2 = atak[c2];
  1398.         /* same for PC1 and PC2 */
  1399.         PC1 = PawnCnt[c1];
  1400.         PC2 = PawnCnt[c2];
  1401.         for (i = PieceCnt[c1]; i >= 0; i--)
  1402.           {
  1403.               sq = PieceList[c1][i];
  1404.               switch (board[sq])
  1405.             {
  1406.             case pawn:
  1407.                 s = PawnValue (sq, side);
  1408.                 break;
  1409.             case knight:
  1410.                 s = KnightValue (sq, side);
  1411.                 break;
  1412.             case bishop:
  1413.                 s = BishopValue (sq, side);
  1414.                 break;
  1415.             case rook:
  1416.                 s = RookValue (sq, side);
  1417.                 break;
  1418.             case queen:
  1419.                 s = QueenValue (sq, side);
  1420.                 break;
  1421.             case king:
  1422.                 s = KingValue (sq, side);
  1423.                 break;
  1424.             default:
  1425.                 s = 0;
  1426.                 break;
  1427.             }
  1428.               pscore[c1] += s;
  1429.               svalue[sq] = s;
  1430.           }
  1431.         }
  1432.     if (hung[side] > 1)
  1433.     pscore[side] += HUNGX;
  1434.     if (hung[xside] > 1)
  1435.     pscore[xside] += HUNGX;
  1436.  
  1437.     score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
  1438. #ifndef NODITHER
  1439.     if (dither)
  1440.       {
  1441.       if (flag.hash)
  1442.           gsrand (starttime + (unsigned int) hashbd);
  1443.       score += urand () % dither;
  1444.       }
  1445. #endif
  1446.     if (score > 0 && pmtl[side] == 0)
  1447.     if (emtl[side] < valueR)
  1448.         score = 0;
  1449.     else if (score < valueR)
  1450.         score /= 2;
  1451.     if (score < 0 && pmtl[xside] == 0)
  1452.     if (emtl[xside] < valueR)
  1453.         score = 0;
  1454.     else if (-score < valueR)
  1455.         score /= 2;
  1456.  
  1457.     if (mtl[xside] == valueK && emtl[side] > valueB)
  1458.     score += 200;
  1459.     if (mtl[side] == valueK && emtl[xside] > valueB)
  1460.     score -= 200;
  1461. #ifdef CACHE
  1462.     if(PUTVAR)PutInEETable(side,score);
  1463. #endif
  1464.     return (score);
  1465. #ifdef CACHE
  1466. }
  1467. else {
  1468. return s;
  1469. }
  1470. #endif
  1471. }
  1472. static inline void
  1473. BlendBoard (const short a[64], const short b[64], short c[64])
  1474. {
  1475.     register int sq, s;
  1476.     s = 10 - stage;
  1477.     for (sq = 0; sq < 64; sq++)
  1478.     c[sq] = ((a[sq] * s) + (b[sq] * stage)) / 10;
  1479. }
  1480.  
  1481.  
  1482. static inline void
  1483. CopyBoard (const short a[64], short b[64])
  1484. {
  1485.     register short *sqa, *sqb;
  1486.     for (sqa = a, sqb = b; sqa < a + 64;)
  1487.     *sqb++ = *sqa++;
  1488. }
  1489.  
  1490.  
  1491. void
  1492. ExaminePosition (void)
  1493.  
  1494. /*
  1495.  * This is done one time before the search is started. Set up arrays Mwpawn,
  1496.  * Mbpawn, Mknight, Mbishop, Mking which are used in the SqValue() function
  1497.  * to determine the positional value of each piece.
  1498.  */
  1499.  
  1500. {
  1501.     register short i, sq;
  1502.     register short fyle;
  1503.     short wpadv, bpadv, wstrong, bstrong, z, side, pp, j, k, val, Pd, rank;
  1504.     static short PawnStorm = false;
  1505.  
  1506.     ataks (white, atak[white]);
  1507.     ataks (black, atak[black]);
  1508.     UpdateWeights ();
  1509.     HasKnight[white] = HasKnight[black] = 0;
  1510.     HasBishop[white] = HasBishop[black] = 0;
  1511.     HasRook[white] = HasRook[black] = 0;
  1512.     HasQueen[white] = HasQueen[black] = 0;
  1513.     for (side = white; side <= black; side++)
  1514.     for (i = PieceCnt[side]; i >= 0; i--)
  1515.         switch (board[PieceList[side][i]])
  1516.           {
  1517.           case knight:
  1518.           ++HasKnight[side];
  1519.           break;
  1520.           case bishop:
  1521.           ++HasBishop[side];
  1522.           break;
  1523.           case rook:
  1524.           ++HasRook[side];
  1525.           break;
  1526.           case queen:
  1527.           ++HasQueen[side];
  1528.           break;
  1529.           }
  1530.     if (!Developed[white])
  1531.     Developed[white] = (board[1] != knight && board[2] != bishop &&
  1532.                 board[5] != bishop && board[6] != knight);
  1533.     if (!Developed[black])
  1534.     Developed[black] = (board[57] != knight && board[58] != bishop &&
  1535.                 board[61] != bishop && board[62] != knight);
  1536.     if (!PawnStorm && stage < 5)
  1537.     PawnStorm = ((column (wking) < 3 && column (bking) > 4) ||
  1538.              (column (wking) > 4 && column (bking) < 3));
  1539.  
  1540.     CopyBoard (pknight, Mknight[white]);
  1541.     CopyBoard (pknight, Mknight[black]);
  1542.     CopyBoard (pbishop, Mbishop[white]);
  1543.     CopyBoard (pbishop, Mbishop[black]);
  1544.     BlendBoard (KingOpening, KingEnding, Mking[white]);
  1545.     BlendBoard (KingOpening, KingEnding, Mking[black]);
  1546.  
  1547.     for (sq = 0; sq < 64; sq++)
  1548.       {
  1549.       fyle = column (sq);
  1550.       rank = row (sq);
  1551.       wstrong = bstrong = true;
  1552.       for (i = sq; i < 64; i += 8)
  1553.           if (Patak (black, i))
  1554.         {
  1555.             wstrong = false;
  1556.             break;
  1557.         }
  1558.       for (i = sq; i >= 0; i -= 8)
  1559.           if (Patak (white, i))
  1560.         {
  1561.             bstrong = false;
  1562.             break;
  1563.         }
  1564.       wpadv = bpadv = PADVNCM;
  1565.       if ((fyle == 0 || PawnCnt[white][fyle - 1] == 0) && (fyle == 7 || PawnCnt[white][fyle + 1] == 0))
  1566.           wpadv = PADVNCI;
  1567.       if ((fyle == 0 || PawnCnt[black][fyle - 1] == 0) && (fyle == 7 || PawnCnt[black][fyle + 1] == 0))
  1568.           bpadv = PADVNCI;
  1569.       Mwpawn[sq] = (wpadv * PawnAdvance[sq]) / 10;
  1570.       Mbpawn[sq] = (bpadv * PawnAdvance[63 - sq]) / 10;
  1571.       Mwpawn[sq] += PawnBonus;
  1572.       Mbpawn[sq] += PawnBonus;
  1573.       if (Mvboard[kingP[white]])
  1574.         {
  1575.         if ((fyle < 3 || fyle > 4) && distance (sq, wking) < 3)
  1576.             Mwpawn[sq] += PAWNSHIELD;
  1577.         }
  1578.       else if (rank < 3 && (fyle < 2 || fyle > 5))
  1579.           Mwpawn[sq] += PAWNSHIELD / 2;
  1580.       if (Mvboard[kingP[black]])
  1581.         {
  1582.         if ((fyle < 3 || fyle > 4) && distance (sq, bking) < 3)
  1583.             Mbpawn[sq] += PAWNSHIELD;
  1584.         }
  1585.       else if (rank > 4 && (fyle < 2 || fyle > 5))
  1586.           Mbpawn[sq] += PAWNSHIELD / 2;
  1587.       if (PawnStorm)
  1588.         {
  1589.         if ((column (wking) < 4 && fyle > 4) || (column (wking) > 3 && fyle < 3))
  1590.             Mwpawn[sq] += 3 * rank - 21;
  1591.         if ((column (bking) < 4 && fyle > 4) || (column (bking) > 3 && fyle < 3))
  1592.             Mbpawn[sq] -= 3 * rank;
  1593.         }
  1594.       Mknight[white][sq] += 5 - distance (sq, bking);
  1595.       Mknight[white][sq] += 5 - distance (sq, wking);
  1596.       Mknight[black][sq] += 5 - distance (sq, wking);
  1597.       Mknight[black][sq] += 5 - distance (sq, bking);
  1598.       Mbishop[white][sq] += BishopBonus;
  1599.       Mbishop[black][sq] += BishopBonus;
  1600.       for (i = PieceCnt[black]; i >= 0; i--)
  1601.           if (distance (sq, PieceList[black][i]) < 3)
  1602.           Mknight[white][sq] += KNIGHTPOST;
  1603.       for (i = PieceCnt[white]; i >= 0; i--)
  1604.           if (distance (sq, PieceList[white][i]) < 3)
  1605.           Mknight[black][sq] += KNIGHTPOST;
  1606.       if (wstrong)
  1607.           Mknight[white][sq] += KNIGHTSTRONG;
  1608.       if (bstrong)
  1609.           Mknight[black][sq] += KNIGHTSTRONG;
  1610.       if (wstrong)
  1611.           Mbishop[white][sq] += BISHOPSTRONG;
  1612.       if (bstrong)
  1613.           Mbishop[black][sq] += BISHOPSTRONG;
  1614.  
  1615.       if (HasBishop[white] == 2)
  1616.           Mbishop[white][sq] += 8;
  1617.       if (HasBishop[black] == 2)
  1618.           Mbishop[black][sq] += 8;
  1619.       if (HasKnight[white] == 2)
  1620.           Mknight[white][sq] += 5;
  1621.       if (HasKnight[black] == 2)
  1622.           Mknight[black][sq] += 5;
  1623.  
  1624.       Kfield[white][sq] = Kfield[black][sq] = 0;
  1625.       if (distance (sq, wking) == 1)
  1626.           Kfield[black][sq] = KATAK;
  1627.       if (distance (sq, bking) == 1)
  1628.           Kfield[white][sq] = KATAK;
  1629.       Pd = 0;
  1630.       for (k = 0; k <= PieceCnt[white]; k++)
  1631.         {
  1632.         i = PieceList[white][k];
  1633.         if (board[i] == pawn)
  1634.           {
  1635.               pp = true;
  1636.               z = i + ((row (i) == 6) ? 8 : 16);
  1637.               for (j = i + 8; j < 64; j += 8)
  1638.               if (Patak (black, j) || board[j] == pawn)
  1639.                 {
  1640.                 pp = false;
  1641.                 break;
  1642.                 }
  1643.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  1644.           }
  1645.         }
  1646.       for (k = 0; k <= PieceCnt[black]; k++)
  1647.         {
  1648.         i = PieceList[black][k];
  1649.         if (board[i] == pawn)
  1650.           {
  1651.               pp = true;
  1652.               z = i - ((row (i) == 1) ? 8 : 16);
  1653.               for (j = i - 8; j >= 0; j -= 8)
  1654.               if (Patak (white, j) || board[j] == pawn)
  1655.                 {
  1656.                 pp = false;
  1657.                 break;
  1658.                 }
  1659.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  1660.           }
  1661.         }
  1662.       if (Pd != 0)
  1663.         {
  1664.         val = (Pd * stage2) / 10;
  1665.         Mking[white][sq] -= val;
  1666.         Mking[black][sq] -= val;
  1667.         }
  1668.       }
  1669. }
  1670.  
  1671. void
  1672. UpdateWeights (void)
  1673.  
  1674. /*
  1675.  * If material balance has changed, determine the values for the positional
  1676.  * evaluation terms.
  1677.  */
  1678.  
  1679. {
  1680.     register short s1;
  1681.  
  1682.     emtl[white] = mtl[white] - pmtl[white] - valueK;
  1683.     emtl[black] = mtl[black] - pmtl[black] - valueK;
  1684.     tmtl = emtl[white] + emtl[black];
  1685.     s1 = ((tmtl > 6600) ? 0 : ((tmtl < 1400) ? 10 : (6600 - tmtl) / 520));
  1686.     if (s1 != stage)
  1687.       {
  1688.       stage = s1;
  1689.       stage2 = ((tmtl > 3600) ? 0 : ((tmtl < 1400) ? 10 : (3600 - tmtl) / 220));
  1690.       PEDRNK2B = -15;    /* centre pawn on 2nd rank & blocked */
  1691.       PBLOK = -4;        /* blocked backward pawn */
  1692.       PDOUBLED = -14;    /* doubled pawn */
  1693.       PWEAKH = -4;        /* weak pawn on half open file */
  1694.       PAWNSHIELD = 10 - stage;    /* pawn near friendly king */
  1695.       PADVNCM = 10;        /* advanced pawn multiplier */
  1696.       PADVNCI = 7;        /* muliplier for isolated pawn */
  1697.       PawnBonus = stage;
  1698.  
  1699.       KNIGHTPOST = (stage + 2) / 3;    /* knight near enemy pieces */
  1700.       KNIGHTSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  1701.  
  1702.       BISHOPSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  1703.       BishopBonus = BBONUS * stage;
  1704.  
  1705.       RHOPN = 10;        /* rook on half open file */
  1706.       RHOPNX = 4;
  1707.       RookBonus = RBONUS * stage;
  1708.  
  1709.       XRAY = 8;        /* Xray attack on piece */
  1710.       PINVAL = 10;        /* Pin */
  1711.  
  1712.       KHOPN = (3 * stage - 30) / 2;    /* king on half open file */
  1713.       KHOPNX = KHOPN / 2;
  1714.       KCASTLD = 10 - stage;
  1715.       KMOVD = -40 / (stage + 1);    /* king moved before castling */
  1716.       KATAK = (10 - stage) / 2;    /* B,R attacks near enemy king */
  1717.       KSFTY = ((stage < 8) ? (KINGSAFETY - 4 * stage) : 0);
  1718.  
  1719.       ATAKD = -6;        /* defender > attacker */
  1720.       HUNGP = -12;        /* each hung piece */
  1721.       HUNGX = -18;        /* extra for >1 hung piece */
  1722.       }
  1723. }
  1724.  
  1725. #else
  1726. /* ............    POSITIONAL EVALUATION ROUTINES    ............ */
  1727.  
  1728. /*
  1729.  * Inputs are:
  1730.  * pmtl[side] - value of pawns
  1731.  * mtl[side]  - value of all material
  1732.  * emtl[side] - vaule of all material - value of pawns - value of king
  1733.  * hung[side] - count of hung pieces
  1734.  * Tscore[ply] - search tree score for ply
  1735.  * ply
  1736.  * Pscore[ply] - positional score for ply ply
  1737.  * INCscore    - bonus score or penalty for certain positions
  1738.  * slk - single lone king flag
  1739.  * Sdepth - search goal depth
  1740.  * xwndw - evaluation window about alpha/beta
  1741.  * EWNDW - second evaluation window about alpha/beta
  1742.  * ChkFlag[ply]- checking piece at level ply or 0 if no check
  1743.  */
  1744. inline
  1745. int
  1746. ScoreKPK (ARGSZ int side,
  1747.       ARGSZ int winner,
  1748.       ARGSZ int loser,
  1749.       ARGSZ int king1,
  1750.       ARGSZ int king2,
  1751.       ARGSZ int sq)
  1752.  
  1753. /*
  1754.  * Score King and Pawns versus King endings.
  1755.  */
  1756.  
  1757. {
  1758.     register short s, r;
  1759.  
  1760.     s = ((PieceCnt[winner] == 1) ? 50 : 120);
  1761.     if (winner == white)
  1762.       {
  1763.       r = row (sq) - ((side == loser) ? 1 : 0);
  1764.       if (row (king2) >= r && distance (sq, king2) < 8 - r)
  1765.           s += 10 * row (sq);
  1766.       else
  1767.           s = 500 + 50 * row (sq);
  1768.       if (row (sq) < 6)
  1769.           sq += 16;
  1770.       else if (row (sq) == 6)
  1771.           sq += 8;
  1772.       }
  1773.     else
  1774.       {
  1775.       r = row (sq) + ((side == loser) ? 1 : 0);
  1776.       if (row (king2) <= r && distance (sq, king2) < r + 1)
  1777.           s += 10 * (7 - row (sq));
  1778.       else
  1779.           s = 500 + 50 * (7 - row (sq));
  1780.       if (row (sq) > 1)
  1781.           sq -= 16;
  1782.       else if (row (sq) == 1)
  1783.           sq -= 8;
  1784.       }
  1785.     s += 8 * (taxicab (king2, sq) - taxicab (king1, sq));
  1786.     return (s);
  1787. }
  1788.  
  1789.  
  1790. short dist_ (short f1, short r1, short f2, short r2)
  1791. {
  1792.   return distdata [ f1-9+8*r1 ][ f2-9+8*r2 ];
  1793. }
  1794.  
  1795. short 
  1796. kpkwv_ (short pf, short pr, short wf, short wr, short bf, short br)
  1797. {
  1798.  
  1799.   /*
  1800.    *  Don Beal's routine, which was originally in Fortran.  See AICC 2
  1801.    */
  1802.  
  1803.  
  1804.   const short drawn=0, win=1;
  1805.   
  1806.   short wbdd, mbpf, blpu;
  1807.   short brpu, mwpf, wlpu, wrpu, blpuu, brpuu, wlpuu, wrpuu, md,
  1808.     bq, blpuuu, brpuuu, bsd, tbf, sgf, bpp, sdr, sgr, wsd, wsg, ppr, wpp;
  1809.  
  1810.  
  1811.   ppr = pr;
  1812.   if (pr == 2) { ppr = 3; }
  1813.   if (pf != 1) { goto L2; }
  1814.   if (bf != 3) { goto L1; }
  1815.   if (pr == 7 && wf == 1 && wr == 8 && br > 6) return drawn;
  1816.   if (pr == 6 && wf < 4 && wr == 6 && br == 8) return win;
  1817. L1:
  1818.   if (bf == 1 && br > pr) return drawn;
  1819.   if (pr == 7 && bf > 2) return win;
  1820.   if (bf <= 3 && br - ppr > 1) return drawn;
  1821.   if (wf == 1 && bf == 3 && wr - pr == 1 && br - pr == 1) return drawn;
  1822. L2:
  1823.   bq = dist_ (bf, br, pf, 8);
  1824.   if (bq > 8 - ppr) return win;
  1825.   mbpf = bf - pf;
  1826.   if (mbpf < 0) { mbpf = -mbpf; }
  1827.   bpp = dist_ (bf, br, pf, ppr);
  1828.   wpp = dist_ (wf, wr, pf, ppr);
  1829.   if (bpp - wpp < -1 && br - pr != mbpf) return drawn;
  1830.   if (pf == 1 && pr <= 3 && wf <= 2 && wr == 8 && bf == 4 && br >= 7) return win;
  1831.   if (pf != 2 || pr != 6 || bf != 1 || br != 8) { goto L3; }
  1832.   if (wf <= 3 && wr == 6) return drawn;
  1833.   if (wf == 4 && wr == 8) return drawn;
  1834. L3:
  1835.   if (pr != 7) { goto L4; }
  1836.   if (wr < 8 && wpp == 2 && bq == 0) return win;
  1837.   if (wr == 6 && wf == pf && bq == 0) return win;
  1838.   if (wr >= 6 && wpp <= 2 && bq != 0) return win;
  1839. L4:
  1840.   blpuu = dist_ (bf, br, pf-1, pr+2);
  1841.   wbdd = dist_ (wf, wr, bf, br-2);
  1842.   brpuu = dist_ (bf, br, pf+1, pr+2);
  1843.   if (pr != 6) { goto L6; }
  1844.   if (dist_ (bf, br, pf+1, pr) > 1 && brpuu > dist_ (wf, wr, pf+1, pr)) return win;
  1845.   if (pf == 1) { goto L5; }
  1846.   if (blpuu > dist_ (wf, wr, pf-1, pr)) return win;
  1847.   if (br == 8 && mbpf == 1 && wbdd == 1) return win;
  1848.   if (br > 6 && mbpf == 2 && dist_ (wf, wr, bf, 5) <= 1) return win;
  1849.   goto L6;
  1850. L5:
  1851.   if (wf == 1 && wr == 8 && bf == 2 && br == 6) return drawn;
  1852. L6:
  1853.   mwpf = wf - pf;
  1854.   if (mwpf < 0) { mwpf = -mwpf; }
  1855.   if (pr >= 5 && mwpf == 2 && wr == pr && bf == wf && br - pr == 2) return win;
  1856.   brpu = dist_ (bf, br, pf+1, pr+1);
  1857.   wrpu = dist_ (wf, wr, pf+1, pr+1);
  1858.   blpu = dist_ (bf, br, pf-1, pr+1);
  1859.   wlpu = dist_ (wf, wr, pf-1, pr+1);
  1860.   if (pf == 1 || pr != 5) { goto L7; }
  1861.   if (mwpf <= 1 && wr - pr == 1) return win;
  1862.   if (wrpu == 1 && brpu > 1) return win;
  1863.   if (wr >= 4 && bf == wf && br - pr >= 2 && mbpf == 3) return win;
  1864.   if (wlpu == 1 && blpu > 1) return win;
  1865. L7:
  1866.   if (pr == 2 && br == 3 && mbpf > 1 && dist_ (wf, wr, bf, br+2) <= 1) return win;
  1867.   if (wr - pr == 2 && br == pr && mbpf == 1 && mwpf > 1 && (wf - pf) *
  1868.       (bf - pf) > 0) return drawn;
  1869.   if (pf == 1 && wf == 1 && wr == br && bf > 3) return win;
  1870.   sgf = pf - 1;
  1871.   if (wf >= pf) { sgf = pf + 1; }
  1872.   sgr = wr - (mwpf - 1);
  1873.   if (mwpf == 0 && wr > br) { sgr = wr - 1; }
  1874.   wsg = dist_ (wf, wr, sgf, sgr);
  1875.   if (wr - pr - mwpf > 0 && wr - br >= -1 && bpp - (wsg + (sgr - ppr))
  1876.       >= -1 && dist_ (bf, br, sgf, sgr) > wsg) return win;
  1877.   md = mbpf - mwpf;
  1878.   if (pf != 1 || bf <= 3) { goto L8; }
  1879.   sdr = br + (bf - 3);
  1880.   if (sdr > 8) { sdr = 8; }
  1881.   if (wr > br + 1) { sdr = br; }
  1882.   if (sdr <= ppr) { goto L8; }
  1883.   wsd = dist_ (wf, wr, 3, sdr);
  1884.   bsd = dist_ (bf, br, 3, sdr);
  1885.   if (bsd - wsd < -1) return drawn;
  1886.   if (bsd <= wsd && md <= 0) return drawn;
  1887. L8:
  1888.   brpuuu = dist_ (bf, br, pf+1, pr+3);
  1889.   if (brpu > wrpu && brpuuu > wrpu && pr - wr != pf - wf) return win;
  1890.   if (brpuuu == 0 && wrpu == 1) return win;
  1891.   blpuuu = dist_ (bf, br, pf-1, pr+3);
  1892.   if (pf == 1) { goto L9; }
  1893.   if (blpu > wlpu && blpuuu > wlpu && pr - wr != wf - pf) return win;
  1894.   if (blpuuu == 0 && wlpu == 1) return win;
  1895. L9:
  1896.   wrpuu = dist_ (wf, wr, pf+1, pr+2);
  1897.   if (brpuu > wrpuu) return win;
  1898.   wlpuu = dist_ (wf, wr, pf-1, pr+2);
  1899.   if (pf > 1 && blpuu > wlpuu) return win;
  1900.   if (br != pr) { goto L10; }
  1901.   if (mwpf <= 2 && wr - pr == -1 && mbpf != 2) return win;
  1902.   if (dist_ (wf, wr, bf-1, br+2) <= 1 && bf - pf > 1) return win;
  1903.   if (dist_ (wf, wr, bf+1, br+2) <= 1 && bf - pf < -1) return win;
  1904. L10:
  1905.   if (pf == 1) { goto L11; }
  1906.   if (br == pr && mbpf > 1 && dist_ (wf, wr, pf, pr-1) <= 1) return win;
  1907.   if (br - pr >= 3 && wbdd == 1) return win;
  1908.   if (wr - pr >= 2 && wr < br && md >= 0) return win;
  1909.   if (mwpf <= 2 && wr - pr >= 3 && bf != pf && wr - br <= 1) return win;
  1910.   if (wr >= pr && br - pr >= 5 && mbpf >= 3 && md >= -1 && ppr == 3) return win;
  1911.   if (md >= -1 && pr == 2 && br == 8) return win;
  1912. L11:
  1913.   tbf = bf - 1;
  1914.   if (pf > bf) { tbf = bf + 1; }
  1915.   if (mbpf > 1 && br == ppr && dist_ (wf, wr, tbf, wr+2) <= 1) return win;
  1916.   if (br == pr && bf - pf == -2 && dist_ (wf, wr, pf+2, pr-1) <= 1) return win;
  1917.   if (pf > 2 && br == pr && bf - pf == 2 && dist_ (wf, wr, pf-2, pr-1) <= 1) return win;
  1918.  
  1919.   return drawn;
  1920. }                /* kpkwv_ */
  1921.  
  1922. short 
  1923. kpkbv_ (short pf, short pr, short wf, short wr, short bf, short br)
  1924. {
  1925.   /* Initialized data */
  1926.  
  1927.   static short incf[8] =
  1928.   {0, 1, 1, 1, 0, -1, -1, -1};
  1929.   static short incr[8] =
  1930.   {1, 1, 0, -1, -1, -1, 0, 1};
  1931.  
  1932.   /* System generated locals */
  1933.   short ret_val;
  1934.  
  1935.   /* Local variables */
  1936.   static short i;
  1937.   static short nm, nbf, nbr;
  1938.  
  1939.   ret_val = 0;
  1940.   nm = 0;
  1941.   for (i = 1; i <= 8; ++i)
  1942.     {
  1943.       nbf = bf + incf[i - 1];
  1944.       if (nbf < 1 || nbf > 8) { goto L1; }
  1945.       nbr = br + incr[i - 1];
  1946.       if (nbr < 1 || nbr > 8) { goto L1; }
  1947.       if (dist_ (nbf, nbr, wf, wr) < 2) { goto L1; }
  1948.       if (nbf == pf && nbr == pr) { goto L2; }
  1949.       if (nbr == pr + 1 && (nbf == pf - 1 || nbf == pf + 1)) { goto L1; }
  1950.       ++nm;
  1951.       if (kpkwv_ (pf, pr, wf, wr, nbf, nbr) == 0) { goto L2; }
  1952.     L1:
  1953.       ;
  1954.     }
  1955.   if (nm > 0) { ret_val = -1; }
  1956. L2:
  1957.   return ret_val;
  1958. }                /* kpkbv_ */
  1959.  
  1960.  
  1961.  
  1962.  
  1963. inline
  1964. int
  1965. ScoreKBNK (ARGSZ int winner, ARGSZ int king1, ARGSZ int king2)
  1966.  
  1967.  
  1968. /*
  1969.  * Score King+Bishop+Knight versus King endings. This doesn't work all that
  1970.  * well but it's better than nothing.
  1971.  */
  1972.  
  1973. {
  1974.     register short s, sq, KBNKsq = 0;
  1975.  
  1976.     for (sq = 0; sq < 64; sq++)
  1977.     if (board[sq] == bishop)
  1978.         KBNKsq = (((row (sq) % 2) == (column (sq) % 2)) ? 0 : 7);
  1979.  
  1980.     s = emtl[winner] - 300;
  1981.     s += ((KBNKsq == 0) ? KBNK[king2] : KBNK[locn (row (king2), 7 - column (king2))]);
  1982.     s -= ((taxicab (king1, king2) + distance (PieceList[winner][1], king2) + distance (PieceList[winner][2], king2)));
  1983.     return (s);
  1984. }
  1985.  
  1986. inline
  1987. int
  1988. ScoreK1PK (short int side,
  1989.        short int winner,
  1990.        short int loser,
  1991.        short int king1,
  1992.        register short int king2,
  1993.        register short int sq)
  1994.  
  1995.      /*
  1996.       *  We call Don Beal's routine with the necessary parameters and determine
  1997.       *  win/draw/loss.  Then we compute the real evaluation which is +-500 for
  1998.       *  a win/loss and 10 for a draw, plus some points to lead the computer to
  1999.       *  a decisive winning/drawing line.
  2000.       */
  2001.  
  2002. {
  2003.   short s, win, sqc, sqr, k1c, k1r, k2c, k2r;
  2004.   const int drawn = 10, won = 500;
  2005.  
  2006. #ifdef CACHE
  2007.   if (ProbeEETable(side,&s)) return s;
  2008. #endif
  2009.  
  2010.   sqc = column (sq) + 1;
  2011.   sqr = row (sq) + 1;
  2012.   k1c = column (king1) + 1;
  2013.   k1r = row (king1) + 1;
  2014.   k2c = column (king2) + 1;
  2015.   k2r = row (king2) + 1;
  2016.   if (winner == black)
  2017.     {
  2018.       sqr = 9 - sqr;
  2019.       k1r = 9 - k1r;
  2020.       k2r = 9 - k2r;
  2021.     }
  2022.   if (sqc > 4)
  2023.     {
  2024.       sqc = 9 - sqc;
  2025.       k1c = 9 - k1c;
  2026.       k2c = 9 - k2c;
  2027.     }
  2028.  
  2029.   if (side == winner) win = kpkwv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  2030.   else                win = kpkbv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  2031.  
  2032.   if (!win)  s = drawn + 5 * distance (sq, king2) - 5*distance(king1,king2);
  2033.   else       s = won + 50 * (sqr - 2) + 10*distance(sq,king2);
  2034. //  if (!win)  s = drawn + 5 * distance (sq, king2); // old 2.50 way
  2035. //  else       s = won + 50 * (sqr - 2); // old 2.50 way
  2036.  
  2037. #ifdef CACHE 
  2038.   if (PUTVAR) PutInEETable (side, s); 
  2039. #endif 
  2040.  
  2041.   return s;
  2042. }
  2043.  
  2044.  
  2045.  
  2046. inline
  2047. short int
  2048. ScoreLoneKing (ARGSZ int side)
  2049.  
  2050. /*
  2051.  * Static evaluation when loser has only a king and winner has no pawns or no
  2052.  * pieces.
  2053.  */
  2054.  
  2055. {
  2056.     register short winner, loser, king1, king2, s, i;
  2057.  
  2058.   if (mtl[white] == valueK && mtl[black] == valueK)
  2059.     return 0;
  2060.     UpdateWeights ();
  2061.     winner = ((mtl[white] > mtl[black]) ? white : black);
  2062.     loser = winner ^ 1;
  2063.     king1 = PieceList[winner][0];
  2064.     king2 = PieceList[loser][0];
  2065.  
  2066.     s = 0;
  2067.  
  2068.   if (pmtl[winner] == 0)
  2069.     {
  2070.     if (emtl[winner] == valueB + valueN)
  2071.       s = ScoreKBNK (winner, king1, king2);
  2072.       else if (emtl[winner] == valueN + valueN || 
  2073.                emtl[winner] == valueN || emtl[winner] == valueB)
  2074.     s = 0; 
  2075.       else
  2076.     s = 500 + emtl[winner] - DyingKing[king2] - 2 * distance (king1, king2);
  2077.     }
  2078.   else {
  2079.     if (pmtl[winner] == valueP)
  2080.         s = ScoreK1PK (side, winner, loser, king1, king2, PieceList[winner][1]);
  2081.       else for (i = 1; i <= PieceCnt[winner]; i++)
  2082.         s += ScoreKPK (side, winner, loser, king1, king2, PieceList[winner][i]);
  2083.     }
  2084.  
  2085.     if (side != winner)
  2086.      s = 0 - s;
  2087.     return(s);
  2088. /*    return ((side == winner) ? s : -s);*/
  2089. }
  2090.  
  2091.  
  2092. int
  2093. evaluate (INTSIZE int side,
  2094.       INTSIZE int ply,
  2095.       INTSIZE int alpha,
  2096.       INTSIZE int beta,
  2097.       INTSIZE int INCscore,
  2098.       short int *InChk)    /* output Check flag */
  2099.  
  2100. /*
  2101.  * Compute an estimate of the score by adding the positional score from the
  2102.  * previous ply to the material difference. If this score falls inside a
  2103.  * window which is 180 points wider than the alpha-beta window (or within a
  2104.  * 50 point window during quiescence search) call ScorePosition() to
  2105.  * determine a score, otherwise return the estimated score. If one side has
  2106.  * only a king and the other either has no pawns or no pieces then the
  2107.  * function ScoreLoneKing() is called.
  2108.  */
  2109.  
  2110. {
  2111.     register short xside;
  2112.     register short int slk;
  2113.     short s;
  2114. /*    int HEVAL=false; seems useless to me! */
  2115.  
  2116.     xside = side ^ 1;
  2117.     s = -Pscore[ply - 1] + mtl[side] - mtl[xside] - INCscore;
  2118.     hung[white] = hung[black] = 0;
  2119.     slk = ((mtl[white] == valueK && (pmtl[black] == 0 || emtl[black] == 0)) ||
  2120.       (mtl[black] == valueK && (pmtl[white] == 0 || emtl[white] == 0)));
  2121.  
  2122.           /* should we use the estimete or score the position */
  2123.     if (!(slk) && (ply == 1 ||
  2124. #ifdef CACHE
  2125.         (/*HEVAL =*/ CheckEETable (side)) ||
  2126. #endif
  2127.     (Sdepth ==  ply) || 
  2128.         (ply > Sdepth && (s >= (alpha - 30) && s <= (beta + 30)) )))
  2129.       {
  2130.       /* score the position */
  2131.       ataks (side, atak[side]);
  2132.       if (Anyatak (side, PieceList[xside][0])){
  2133.       ataks (xside, atak[xside]);
  2134.       *InChk = Anyatak (xside, PieceList[side][0]);
  2135.           return (10001 - ply);
  2136.       }
  2137.       ataks (xside, atak[xside]);
  2138.       *InChk = Anyatak (xside, PieceList[side][0]);
  2139. #ifndef BAREBONES 
  2140.       EvalNodes++;
  2141. #endif
  2142.     if(ply>4)PUTVAR=true;
  2143.           s = ScorePosition (side);
  2144.     PUTVAR=false;
  2145.       }
  2146.     else
  2147.       {
  2148.       /* use the estimate but look at check and slk */
  2149.       *InChk = SqAtakd (PieceList[side][0], xside);
  2150.       if (SqAtakd (PieceList[xside][0], side)){
  2151.           return (10001 - ply);
  2152.       }
  2153.  
  2154.       if (slk) {
  2155.         if (ply>4) PUTVAR=true;
  2156.             s = ScoreLoneKing (side);
  2157.             PUTVAR=false;
  2158.             }
  2159.       }
  2160.  
  2161.     Pscore[ply] = s - mtl[side] + mtl[xside];
  2162.     ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] + 1 : 0);
  2163.     return (s);
  2164. }
  2165.  
  2166. inline
  2167. int
  2168. BRscan (ARGSZ int sq, short int *mob)
  2169.  
  2170. /*
  2171.  * Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the
  2172.  * hung[] array if a pin is found.
  2173.  */
  2174. {
  2175.     register unsigned char *ppos, *pdir;
  2176.     register short s, mobx;
  2177.     register short u, pin;
  2178.     short piece, *Kf;
  2179.     mobx = s = 0;
  2180.     Kf = Kfield[c1];
  2181.     piece = board[sq];
  2182.     ppos = nextpos[piece][sq];
  2183.     pdir = nextdir[piece][sq];
  2184.     u = ppos[sq];
  2185.     pin = -1;            /* start new direction */
  2186.     do
  2187.       {
  2188.       s += Kf[u];
  2189.       if (color[u] == neutral)
  2190.         {
  2191.         mobx++;
  2192.         if (ppos[u] == pdir[u])
  2193.             pin = -1;    /* oops new direction */
  2194.         u = ppos[u];
  2195.         }
  2196.       else if (pin < 0)
  2197.         {
  2198.         if (board[u] == pawn || board[u] == king)
  2199.             u = pdir[u];
  2200.         else
  2201.           {
  2202.               if (ppos[u] != pdir[u])
  2203.               pin = u;    /* not on the edge and on to find a pin */
  2204.               u = ppos[u];
  2205.           }
  2206.         }
  2207.       else
  2208.         {
  2209.         if (color[u] == c2 && (board[u] > piece || atk2[u] == 0))
  2210.           {
  2211.               if (color[pin] == c2)
  2212.             {
  2213.                 s += PINVAL;
  2214.                 if (atk2[pin] == 0 || atk1[pin] > control[board[pin]] + 1)
  2215.                 ++hung[c2];
  2216.             }
  2217.               else
  2218.               s += XRAY;
  2219.           }
  2220.         pin = -1;    /* new direction */
  2221.         u = pdir[u];
  2222.         }
  2223.       }
  2224.     while (u != sq);
  2225.     *mob = mobx;
  2226.     return s;
  2227. }
  2228.  
  2229. inline
  2230. short int
  2231. KingScan (ARGSZ int sq)
  2232.  
  2233. /*
  2234.  * Assign penalties if king can be threatened by checks, if squares near the
  2235.  * king are controlled by the enemy (especially the queen), or if there are
  2236.  * no pawns near the king. The following must be true: board[sq] == king c1
  2237.  * == color[sq] c2 == otherside[c1]
  2238.  */
  2239.  
  2240. #define ScoreThreat \
  2241.     if (color[u] != c2)\
  2242.       if (atk1[u] == 0 || (atk2[u] & 0xFF) > 1) ++cnt;\
  2243.       else s -= 3
  2244.  
  2245. {
  2246.     register short cnt;
  2247.     register unsigned char *ppos, *pdir;
  2248.     register short int s;
  2249.     register short u;
  2250.     short int ok;
  2251.  
  2252.     s = 0;
  2253.     cnt = 0;
  2254.     if (HasBishop[c2] || HasQueen[c2])
  2255.       {
  2256.       ppos = nextpos[bishop][sq];
  2257.       pdir = nextdir[bishop][sq];
  2258.       u = ppos[sq];
  2259.       do
  2260.         {
  2261.         if (atk2[u] & ctlBQ)
  2262.             ScoreThreat;
  2263.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  2264.         }
  2265.       while (u != sq);
  2266.       }
  2267.     if (HasRook[c2] || HasQueen[c2])
  2268.       {
  2269.       ppos = nextpos[rook][sq];
  2270.       pdir = nextdir[rook][sq];
  2271.       u = ppos[sq];
  2272.       do
  2273.         {
  2274.         if (atk2[u] & ctlRQ)
  2275.             ScoreThreat;
  2276.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  2277.         }
  2278.       while (u != sq);
  2279.       }
  2280.     if (HasKnight[c2])
  2281.       {
  2282.       pdir = nextdir[knight][sq];
  2283.       u = pdir[sq];
  2284.       do
  2285.         {
  2286.         if (atk2[u] & ctlNN)
  2287.             ScoreThreat;
  2288.         u = pdir[u];
  2289.         }
  2290.       while (u != sq);
  2291.       }
  2292.     s += (KSFTY * KTHRT[cnt]) / 16;
  2293.  
  2294.     cnt = 0;
  2295.     ok = false;
  2296.     pdir = nextpos[king][sq];
  2297.     u = pdir[sq];
  2298.     do
  2299.       {
  2300.       if (board[u] == pawn)
  2301.           ok = true;
  2302.       if (atk2[u] > atk1[u])
  2303.         {
  2304.         ++cnt;
  2305.         if (atk2[u] & ctlQ)
  2306.             if (atk2[u] > ctlQ + 1 && atk1[u] < ctlQ)
  2307.             s -= 4 * KSFTY;
  2308.         }
  2309.       u = pdir[u];
  2310.       }
  2311.     while (u != sq);
  2312.     if (!ok)
  2313.     s -= KSFTY;
  2314.     if (cnt > 1)
  2315.     s -= (KSFTY);
  2316.     return (s);
  2317. }
  2318.  
  2319. inline
  2320. int
  2321. trapped (ARGSZ int sq)
  2322.  
  2323. /*
  2324.  * See if the attacked piece has unattacked squares to move to. The following
  2325.  * must be true: c1 == color[sq] c2 == otherside[c1]
  2326.  */
  2327.  
  2328. {
  2329.     register short u;
  2330.     register unsigned char *ppos, *pdir;
  2331.     register short int piece;
  2332.  
  2333.     piece = board[sq];
  2334.     ppos = nextpos[ptype[c1][piece]][sq];
  2335.     pdir = nextdir[ptype[c1][piece]][sq];
  2336.     if (piece == pawn)
  2337.       {
  2338.       u = ppos[sq];        /* follow no captures thread */
  2339.       if (color[u] == neutral)
  2340.         {
  2341.         if (atk1[u] >= atk2[u])
  2342.             return (false);
  2343.         if (atk2[u] < ctlP)
  2344.           {
  2345.               u = ppos[u];
  2346.               if (color[u] == neutral && atk1[u] >= atk2[u])
  2347.               return (false);
  2348.           }
  2349.         }
  2350.       u = pdir[sq];        /* follow captures thread */
  2351.       if (color[u] == c2)
  2352.           return (false);
  2353.       u = pdir[u];
  2354.       if (color[u] == c2)
  2355.           return (false);
  2356.       }
  2357.     else
  2358.       {
  2359.       u = ppos[sq];
  2360.       do
  2361.         {
  2362.         if (color[u] != c1)
  2363.             if (atk2[u] == 0 || board[u] >= piece)
  2364.             return (false);
  2365.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  2366.         }
  2367.       while (u != sq);
  2368.       }
  2369.     return (true);
  2370. }
  2371.  
  2372.  
  2373. static inline int
  2374. PawnValue (ARGSZ int sq, ARGSZ int side)
  2375. /*
  2376.  * Calculate the positional value for a pawn on 'sq'.
  2377.  */
  2378.  
  2379. {
  2380.     register short fyle, rank;
  2381.     register short j, s, a1, a2, in_square, r, e;
  2382.  
  2383.     a1 = (atk1[sq] & 0x4FFF);
  2384.     a2 = (atk2[sq] & 0x4FFF);
  2385.     rank = row (sq);
  2386.     fyle = column (sq);
  2387.     s = 0;
  2388.     if (c1 == white)
  2389.       {
  2390.       s = Mwpawn[sq];
  2391.       if ((sq == 11 && color[19] != neutral)
  2392.           || (sq == 12 && color[20] != neutral))
  2393.           s += PEDRNK2B;
  2394.       if ((fyle == 0 || PC1[fyle - 1] == 0)
  2395.           && (fyle == 7 || PC1[fyle + 1] == 0))
  2396.           s += ISOLANI[fyle];
  2397.       else if (PC1[fyle] > 1)
  2398.           s += PDOUBLED;
  2399.       if (a1 < ctlP && atk1[sq + 8] < ctlP)
  2400.         {
  2401.         s += BACKWARD[a2 & 0xFF];
  2402.         if (PC2[fyle] == 0)
  2403.             s += PWEAKH;
  2404.         if (color[sq + 8] != neutral)
  2405.             s += PBLOK;
  2406.         }
  2407.       if (PC2[fyle] == 0)
  2408.         {
  2409.         if (side == black)
  2410.             r = rank - 1;
  2411.         else
  2412.             r = rank;
  2413.         in_square = (row (bking) >= r && distance (sq, bking) < 8 - r);
  2414.         if (a2 == 0 || side == white)
  2415.             e = 0;
  2416.         else
  2417.             e = 1;
  2418.         for (j = sq + 8; j < 64; j += 8)
  2419.             if (atk2[j] >= ctlP)
  2420.               {
  2421.               e = 2;
  2422.               break;
  2423.               }
  2424.             else if (atk2[j] > 0 || color[j] != neutral)
  2425.             e = 1;
  2426.         if (e == 2)
  2427.             s += (stage * PassedPawn3[rank]) / 10;
  2428.         else if (in_square || e == 1)
  2429.             s += (stage * PassedPawn2[rank]) / 10;
  2430.         else if (emtl[black] > 0)
  2431.             s += (stage * PassedPawn1[rank]) / 10;
  2432.         else
  2433.             s += PassedPawn0[rank];
  2434.         }
  2435.       }
  2436.     else if (c1 == black)
  2437.       {
  2438.       s = Mbpawn[sq];
  2439.       if ((sq == 51 && color[43] != neutral)
  2440.           || (sq == 52 && color[44] != neutral))
  2441.           s += PEDRNK2B;
  2442.       if ((fyle == 0 || PC1[fyle - 1] == 0) &&
  2443.           (fyle == 7 || PC1[fyle + 1] == 0))
  2444.           s += ISOLANI[fyle];
  2445.       else if (PC1[fyle] > 1)
  2446.           s += PDOUBLED;
  2447.       if (a1 < ctlP && atk1[sq - 8] < ctlP)
  2448.         {
  2449.         s += BACKWARD[a2 & 0xFF];
  2450.         if (PC2[fyle] == 0)
  2451.             s += PWEAKH;
  2452.         if (color[sq - 8] != neutral)
  2453.             s += PBLOK;
  2454.         }
  2455.       if (PC2[fyle] == 0)
  2456.         {
  2457.         if (side == white)
  2458.             r = rank + 1;
  2459.         else
  2460.             r = rank;
  2461.         in_square = (row (wking) <= r && distance (sq, wking) < r + 1);
  2462.         if (a2 == 0 || side == black)
  2463.             e = 0;
  2464.         else
  2465.             e = 1;
  2466.         for (j = sq - 8; j >= 0; j -= 8)
  2467.             if (atk2[j] >= ctlP)
  2468.               {
  2469.               e = 2;
  2470.               break;
  2471.               }
  2472.             else if (atk2[j] > 0 || color[j] != neutral)
  2473.             e = 1;
  2474.         if (e == 2)
  2475.             s += (stage * PassedPawn3[7 - rank]) / 10;
  2476.         else if (in_square || e == 1)
  2477.             s += (stage * PassedPawn2[7 - rank]) / 10;
  2478.         else if (emtl[white] > 0)
  2479.             s += (stage * PassedPawn1[7 - rank]) / 10;
  2480.         else
  2481.             s += PassedPawn0[7 - rank];
  2482.         }
  2483.       }
  2484.     if (a2 > 0)
  2485.       {
  2486.       if (a1 == 0 || a2 > ctlP + 1)
  2487.         {
  2488.         s += HUNGP;
  2489.         if (trapped (sq))
  2490.             hung[c1] += 2;
  2491.         hung[c1]++;
  2492.         }
  2493.       else if (a2 > a1)
  2494.           s += ATAKD;
  2495.       }
  2496.     return (s);
  2497. }
  2498.  
  2499. inline
  2500. int
  2501. KnightValue (ARGSZ int sq)
  2502.  
  2503. /*
  2504.  * Calculate the positional value for a knight on 'sq'.
  2505.  */
  2506.  
  2507. {
  2508.     register short s, a2, a1;
  2509.  
  2510.     s = Mknight[c1][sq];
  2511.     a2 = (atk2[sq] & 0x4FFF);
  2512.     if (a2 > 0)
  2513.       {
  2514.       a1 = (atk1[sq] & 0x4FFF);
  2515.       if (a1 == 0 || a2 > ctlBN + 1)
  2516.         {
  2517.         s += HUNGP;
  2518.         if (trapped (sq))
  2519.             hung[c1] += 2;
  2520.         hung[c1]++;
  2521.         }
  2522.       else if (a2 >= ctlBN || a1 < ctlP)
  2523.           s += ATAKD;
  2524.       }
  2525.     return (s);
  2526. }
  2527.  
  2528. inline
  2529. int
  2530. BishopValue (ARGSZ int sq)
  2531.  
  2532. /*
  2533.  * Calculate the positional value for a bishop on 'sq'.
  2534.  */
  2535.  
  2536. {
  2537.     register short s;
  2538.     register short a2, a1;
  2539.     short mob;
  2540.  
  2541.     s = Mbishop[c1][sq];
  2542.     s += BRscan (sq, &mob);
  2543.     s += BMBLTY[mob];
  2544.     a2 = (atk2[sq] & 0x4FFF);
  2545.     if (a2 > 0)
  2546.       {
  2547.       a1 = (atk1[sq] & 0x4FFF);
  2548.       if (a1 == 0 || a2 > ctlBN + 1)
  2549.         {
  2550.         s += HUNGP;
  2551.         if (trapped (sq))
  2552.             hung[c1] += 2;
  2553.         hung[c1]++;
  2554.         }
  2555.       else if (a2 >= ctlBN || a1 < ctlP)
  2556.           s += ATAKD;
  2557.       }
  2558.     return (s);
  2559. }
  2560.  
  2561. inline
  2562. int
  2563. RookValue (ARGSZ int sq)
  2564.  
  2565. /*
  2566.  * Calculate the positional value for a rook on 'sq'.
  2567.  */
  2568.  
  2569. {
  2570.     register short s;
  2571.     register short fyle, a2, a1;
  2572.     short mob;
  2573.  
  2574.     s = RookBonus;
  2575.     s += BRscan (sq, &mob);
  2576.     s += RMBLTY[mob];
  2577.     fyle = column (sq);
  2578.     if (PC1[fyle] == 0)
  2579.      {
  2580.     s += RHOPN;
  2581.             if (PC2[fyle] == 0)
  2582.             s += RHOPNX;
  2583.      }
  2584.     if (pmtl[c2] > 100 && row (sq) == rank7[c1])
  2585.     s += 10;
  2586.     if (stage > 2)
  2587.     s += 14 - taxicab (sq, EnemyKing);
  2588.     a2 = (atk2[sq] & 0x4FFF);
  2589.     if (a2 > 0)
  2590.       {
  2591.       a1 = (atk1[sq] & 0x4FFF);
  2592.       if (a1 == 0 || a2 > ctlR + 1)
  2593.         {
  2594.         s += HUNGP;
  2595.         if (trapped (sq))
  2596.             hung[c1] += 2;
  2597.         hung[c1]++;
  2598.         }
  2599.       else if (a2 >= ctlR || a1 < ctlP)
  2600.           s += ATAKD;
  2601.       }
  2602.     return (s);
  2603. }
  2604.  
  2605. inline
  2606. int
  2607. QueenValue (ARGSZ int sq)
  2608.  
  2609. /*
  2610.  * Calculate the positional value for a queen on 'sq'.
  2611.  */
  2612.  
  2613. {
  2614.     register short s, a2, a1;
  2615.  
  2616.     s = ((distance (sq, EnemyKing) < 3) ? 12 : 0);
  2617.     if (stage > 2)
  2618.     s += 14 - taxicab (sq, EnemyKing);
  2619.     a2 = (atk2[sq] & 0x4FFF);
  2620.     if (a2 > 0)
  2621.       {
  2622.       a1 = (atk1[sq] & 0x4FFF);
  2623.       if (a1 == 0 || a2 > ctlQ + 1)
  2624.         {
  2625.         s += HUNGP;
  2626.         if (trapped (sq))
  2627.             hung[c1] += 2;
  2628.         hung[c1]++;
  2629.         }
  2630.       else if (a2 >= ctlQ || a1 < ctlP)
  2631.           s += ATAKD;
  2632.       }
  2633.     return (s);
  2634. }
  2635.  
  2636. inline
  2637. int
  2638. KingValue (ARGSZ int sq, ARGSZ int side)
  2639.  
  2640. /*
  2641.  * Calculate the positional value for a king on 'sq'.
  2642.  */
  2643.  
  2644. {
  2645.     register short s;
  2646.     register short fyle;
  2647.     short int a2, a1;
  2648.     s = (emtl[side ^ 1] > KINGPOSLIMIT) ? Mking[c1][sq] : Mking[c1][sq] / 2;
  2649.     if (KSFTY > 0)
  2650.     if (Developed[c2] || stage > 0)
  2651.         s += KingScan (sq);
  2652.     if (castld[c1])
  2653.     s += KCASTLD;
  2654.     else if (Mvboard[kingP[c1]])
  2655.     s += KMOVD;
  2656.  
  2657.     fyle = column (sq);
  2658.     if (PC1[fyle] == 0)
  2659.     s += KHOPN;
  2660.     if (PC2[fyle] == 0)
  2661.     s += KHOPNX;
  2662.     switch (fyle)
  2663.       {
  2664.       case 5:
  2665.       if (PC1[7] == 0)
  2666.           s += KHOPN;
  2667.       if (PC2[7] == 0)
  2668.           s += KHOPNX;
  2669.       /* Fall through */
  2670.       case 4:
  2671.       case 6:
  2672.       case 0:
  2673.       if (PC1[fyle + 1] == 0)
  2674.           s += KHOPN;
  2675.       if (PC2[fyle + 1] == 0)
  2676.           s += KHOPNX;
  2677.       break;
  2678.       case 2:
  2679.       if (PC1[0] == 0)
  2680.           s += KHOPN;
  2681.       if (PC2[0] == 0)
  2682.           s += KHOPNX;
  2683.       /* Fall through */
  2684.       case 3:
  2685.       case 1:
  2686.       case 7:
  2687.       if (PC1[fyle - 1] == 0)
  2688.           s += KHOPN;
  2689.       if (PC2[fyle - 1] == 0)
  2690.           s += KHOPNX;
  2691.       break;
  2692.       default:
  2693.       /* Impossible! */
  2694.       break;
  2695.       }
  2696.  
  2697.     a2 = (atk2[sq] & 0x4FFF);
  2698.     if (a2 > 0)
  2699.       {
  2700.       a1 = (atk1[sq] & 0x4FFF);
  2701.       if (a1 == 0 || a2 > ctlK + 1)
  2702.         {
  2703.         s += HUNGP;
  2704.         ++hung[c1];
  2705.         }
  2706.       else
  2707.           s += ATAKD;
  2708.       }
  2709.     return (s);
  2710. }
  2711.  
  2712.  
  2713. short int
  2714. ScorePosition (register short int side)
  2715.  
  2716. /*
  2717.  * Perform normal static evaluation of board position. A score is generated
  2718.  * for each piece and these are summed to get a score for each side.
  2719.  */
  2720.  
  2721. {
  2722.     register short int score;
  2723.     register short sq, i, xside;
  2724.     short int s;
  2725.  
  2726.     UpdateWeights ();
  2727.     xside = side ^ 1;
  2728.     hung[white] = hung[black] = pscore[white] = pscore[black] = 0;
  2729. #ifdef CACHE
  2730.     if (!ProbeEETable (side, &s))
  2731.       {
  2732. #endif
  2733.       for (c1 = white; c1 <= black; c1++)
  2734.         {
  2735.         c2 = c1 ^ 1;
  2736.         /* atk1 is array of atacks on squares by my side */
  2737.         atk1 = atak[c1];
  2738.         /* atk2 is array of atacks on squares by other side */
  2739.         atk2 = atak[c2];
  2740.         /* same for PC1 and PC2 */
  2741.         PC1 = PawnCnt[c1];
  2742.         PC2 = PawnCnt[c2];
  2743.         for (i = PieceCnt[c1]; i >= 0; i--)
  2744.           {
  2745.               sq = PieceList[c1][i];
  2746.               switch (board[sq])
  2747.             {
  2748.             case pawn:
  2749.                 s = PawnValue (sq, side);
  2750.                 break;
  2751.             case knight:
  2752.                 s = KnightValue (sq);
  2753.                 break;
  2754.             case bishop:
  2755.                 s = BishopValue (sq);
  2756.                 break;
  2757.             case rook:
  2758.                 s = RookValue (sq);
  2759.                 break;
  2760.             case queen:
  2761.                 s = QueenValue (sq);
  2762.                 break;
  2763.             case king:
  2764.                 s = KingValue (sq, side);
  2765.                 break;
  2766.             default:
  2767.                 s = 0;
  2768.                 break;
  2769.             }
  2770.               pscore[c1] += s;
  2771.               svalue[sq] = s;
  2772.           }
  2773.         }
  2774.     if (hung[side] > 1)
  2775.     pscore[side] += HUNGX;
  2776.     if (hung[xside] > 1)
  2777.     pscore[xside] += HUNGX;
  2778.  
  2779.     score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
  2780.     if (dither)
  2781.       {
  2782.       if (flag.hash)
  2783.           gsrand (starttime + (unsigned int) hashbd);
  2784.       score += urand () % dither;
  2785.       }
  2786.  
  2787.     if (score > 0 && pmtl[side] == 0)
  2788.     if (emtl[side] < valueR)
  2789.         score = 0;
  2790.     else if (score < valueR)
  2791.         score /= 2;
  2792.     if (score < 0 && pmtl[xside] == 0)
  2793.     if (emtl[xside] < valueR)
  2794.         score = 0;
  2795.     else if (-score < valueR)
  2796.         score /= 2;
  2797.  
  2798.     if (mtl[xside] == valueK && emtl[side] > valueB)
  2799.     score += 200;
  2800.     if (mtl[side] == valueK && emtl[xside] > valueB)
  2801.     score -= 200;
  2802. #ifdef CACHE
  2803.     if(PUTVAR)PutInEETable(side,score);
  2804. #endif
  2805.     return (score);
  2806. #ifdef CACHE
  2807. }
  2808. else {
  2809. return s;
  2810. }
  2811. #endif
  2812. }
  2813.  
  2814.  
  2815. static inline void
  2816. BlendBoard (const short int a[64], const short int b[64], short int c[64])
  2817. {
  2818.     register int sq, s;
  2819.     s = 10 - stage;
  2820.     for (sq = 0; sq < 64; sq++)
  2821.     c[sq] = ((a[sq] * s) + (b[sq] * stage)) / 10;
  2822. }
  2823.  
  2824.  
  2825. static inline void
  2826. CopyBoard (const short int a[64], short int b[64])
  2827. {
  2828. #ifndef AMIGA
  2829.     register short *sqa, *sqb;
  2830.  
  2831.     for (sqa = (short *)a, sqb = b; sqa < a + 64;)
  2832.     *sqb++ = *sqa++;
  2833. #else
  2834.  MoveMem128(a,b);
  2835. /* MoveMem(a,b,64*sizeof(short));*/
  2836. #endif
  2837. }
  2838.  
  2839.  
  2840. void
  2841. ExaminePosition (void)
  2842.  
  2843. /*
  2844.  * This is done one time before the search is started. Set up arrays Mwpawn,
  2845.  * Mbpawn, Mknight, Mbishop, Mking which are used in the SqValue() function
  2846.  * to determine the positional value of each piece.
  2847.  */
  2848.  
  2849. {
  2850.     register short i, sq;
  2851.     register short fyle;
  2852.     short wpadv, bpadv, wstrong, bstrong, z, side, pp, j, k, val, Pd, rank;
  2853.     static short PawnStorm = false;
  2854.  
  2855.     ataks (white, atak[white]);
  2856.     ataks (black, atak[black]);
  2857.     UpdateWeights ();
  2858.     HasKnight[white] = HasKnight[black] = 0;
  2859.     HasBishop[white] = HasBishop[black] = 0;
  2860.     HasRook[white] = HasRook[black] = 0;
  2861.     HasQueen[white] = HasQueen[black] = 0;
  2862.     for (side = white; side <= black; side++)
  2863.     for (i = PieceCnt[side]; i >= 0; i--)
  2864.         switch (board[PieceList[side][i]])
  2865.           {
  2866.           case knight:
  2867.           ++HasKnight[side];
  2868.           break;
  2869.           case bishop:
  2870.           ++HasBishop[side];
  2871.           break;
  2872.           case rook:
  2873.           ++HasRook[side];
  2874.           break;
  2875.           case queen:
  2876.           ++HasQueen[side];
  2877.           break;
  2878.           }
  2879.     if (!Developed[white])
  2880.     Developed[white] = (board[1] != knight && board[2] != bishop &&
  2881.                 board[5] != bishop && board[6] != knight);
  2882.     if (!Developed[black])
  2883.     Developed[black] = (board[57] != knight && board[58] != bishop &&
  2884.                 board[61] != bishop && board[62] != knight);
  2885.     if (!PawnStorm && stage < 5)
  2886.     PawnStorm = ((column (wking) < 3 && column (bking) > 4) ||
  2887.              (column (wking) > 4 && column (bking) < 3));
  2888.  
  2889.     CopyBoard (pknight, Mknight[white]);
  2890.     CopyBoard (pknight, Mknight[black]);
  2891.     CopyBoard (pbishop, Mbishop[white]);
  2892.     CopyBoard (pbishop, Mbishop[black]);
  2893.     BlendBoard (KingOpening, KingEnding, Mking[white]);
  2894.     BlendBoard (KingOpening, KingEnding, Mking[black]);
  2895.  
  2896.     for (sq = 0; sq < 64; sq++)
  2897.       {
  2898.       fyle = column (sq);
  2899.       rank = row (sq);
  2900.       wstrong = bstrong = true;
  2901.       for (i = sq; i < 64; i += 8)
  2902.           if (Patak (black, i))
  2903.         {
  2904.             wstrong = false;
  2905.             break;
  2906.         }
  2907.       for (i = sq; i >= 0; i -= 8)
  2908.           if (Patak (white, i))
  2909.         {
  2910.             bstrong = false;
  2911.             break;
  2912.         }
  2913.       wpadv = bpadv = PADVNCM;
  2914.       if ((fyle == 0 || PawnCnt[white][fyle - 1] == 0) && (fyle == 7 || PawnCnt[white][fyle + 1] == 0))
  2915.           wpadv = PADVNCI;
  2916.       if ((fyle == 0 || PawnCnt[black][fyle - 1] == 0) && (fyle == 7 || PawnCnt[black][fyle + 1] == 0))
  2917.           bpadv = PADVNCI;
  2918.       Mwpawn[sq] = (wpadv * PawnAdvance[sq]) / 10;
  2919.       Mbpawn[sq] = (bpadv * PawnAdvance[63 - sq]) / 10;
  2920.       Mwpawn[sq] += PawnBonus;
  2921.       Mbpawn[sq] += PawnBonus;
  2922.       if (Mvboard[kingP[white]])
  2923.         {
  2924.         if ((fyle < 3 || fyle > 4) && distance (sq, wking) < 3)
  2925.             Mwpawn[sq] += PAWNSHIELD;
  2926.         }
  2927.       else if (rank < 3 && (fyle < 2 || fyle > 5))
  2928.           Mwpawn[sq] += PAWNSHIELD / 2;
  2929.       if (Mvboard[kingP[black]])
  2930.         {
  2931.         if ((fyle < 3 || fyle > 4) && distance (sq, bking) < 3)
  2932.             Mbpawn[sq] += PAWNSHIELD;
  2933.         }
  2934.       else if (rank > 4 && (fyle < 2 || fyle > 5))
  2935.           Mbpawn[sq] += PAWNSHIELD / 2;
  2936.       if (PawnStorm)
  2937.         {
  2938.         if ((column (wking) < 4 && fyle > 4) || (column (wking) > 3 && fyle < 3))
  2939.             Mwpawn[sq] += 3 * rank - 21;
  2940.         if ((column (bking) < 4 && fyle > 4) || (column (bking) > 3 && fyle < 3))
  2941.             Mbpawn[sq] -= 3 * rank;
  2942.         }
  2943.       Mknight[white][sq] += 5 - distance (sq, bking);
  2944.       Mknight[white][sq] += 5 - distance (sq, wking);
  2945.       Mknight[black][sq] += 5 - distance (sq, wking);
  2946.       Mknight[black][sq] += 5 - distance (sq, bking);
  2947.       Mbishop[white][sq] += BishopBonus;
  2948.       Mbishop[black][sq] += BishopBonus;
  2949.       for (i = PieceCnt[black]; i >= 0; i--)
  2950.           if (distance (sq, PieceList[black][i]) < 3)
  2951.           Mknight[white][sq] += KNIGHTPOST;
  2952.       for (i = PieceCnt[white]; i >= 0; i--)
  2953.           if (distance (sq, PieceList[white][i]) < 3)
  2954.           Mknight[black][sq] += KNIGHTPOST;
  2955.       if (wstrong)
  2956.           Mknight[white][sq] += KNIGHTSTRONG;
  2957.       if (bstrong)
  2958.           Mknight[black][sq] += KNIGHTSTRONG;
  2959.       if (wstrong)
  2960.           Mbishop[white][sq] += BISHOPSTRONG;
  2961.       if (bstrong)
  2962.           Mbishop[black][sq] += BISHOPSTRONG;
  2963.  
  2964.       if (HasBishop[white] == 2)
  2965.           Mbishop[white][sq] += 8;
  2966.       if (HasBishop[black] == 2)
  2967.           Mbishop[black][sq] += 8;
  2968.       if (HasKnight[white] == 2)
  2969.           Mknight[white][sq] += 5;
  2970.       if (HasKnight[black] == 2)
  2971.           Mknight[black][sq] += 5;
  2972.  
  2973.       Kfield[white][sq] = Kfield[black][sq] = 0;
  2974.       if (distance (sq, wking) == 1)
  2975.           Kfield[black][sq] = KATAK;
  2976.       if (distance (sq, bking) == 1)
  2977.           Kfield[white][sq] = KATAK;
  2978.       Pd = 0;
  2979.       for (k = 0; k <= PieceCnt[white]; k++)
  2980.         {
  2981.         i = PieceList[white][k];
  2982.         if (board[i] == pawn)
  2983.           {
  2984.               pp = true;
  2985.               z = i + ((row (i) == 6) ? 8 : 16);
  2986.               for (j = i + 8; j < 64; j += 8)
  2987.               if (Patak (black, j) || board[j] == pawn)
  2988.                 {
  2989.                 pp = false;
  2990.                 break;
  2991.                 }
  2992.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  2993.           }
  2994.         }
  2995.       for (k = 0; k <= PieceCnt[black]; k++)
  2996.         {
  2997.         i = PieceList[black][k];
  2998.         if (board[i] == pawn)
  2999.           {
  3000.               pp = true;
  3001.               z = i - ((row (i) == 1) ? 8 : 16);
  3002.               for (j = i - 8; j >= 0; j -= 8)
  3003.               if (Patak (white, j) || board[j] == pawn)
  3004.                 {
  3005.                 pp = false;
  3006.                 break;
  3007.                 }
  3008.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  3009.           }
  3010.         }
  3011.       if (Pd != 0)
  3012.         {
  3013.         val = (Pd * stage2) / 10;
  3014.         Mking[white][sq] -= val;
  3015.         Mking[black][sq] -= val;
  3016.         }
  3017.       }
  3018. }
  3019.  
  3020. void
  3021. UpdateWeights (void)
  3022.  
  3023. /*
  3024.  * If material balance has changed, determine the values for the positional
  3025.  * evaluation terms.
  3026.  */
  3027.  
  3028. {
  3029.     register short s1;
  3030.  
  3031.     emtl[white] = mtl[white] - pmtl[white] - valueK;
  3032.     emtl[black] = mtl[black] - pmtl[black] - valueK;
  3033.     tmtl = emtl[white] + emtl[black];
  3034.     s1 = ((tmtl > 6600) ? 0 : ((tmtl < 1400) ? 10 : (6600 - tmtl) / 520));
  3035.     if (s1 != stage)
  3036.       {
  3037.       stage = s1;
  3038.       stage2 = ((tmtl > 3600) ? 0 : ((tmtl < 1400) ? 10 : (3600 - tmtl) / 220));
  3039.       PEDRNK2B = -15;    /* centre pawn on 2nd rank & blocked */
  3040.       PBLOK = -4;        /* blocked backward pawn */
  3041.       PDOUBLED = -14;    /* doubled pawn */
  3042.       PWEAKH = -4;        /* weak pawn on half open file */
  3043.       PAWNSHIELD = 10 - stage;    /* pawn near friendly king */
  3044.       PADVNCM = 10;        /* advanced pawn multiplier */
  3045.       PADVNCI = 7;        /* muliplier for isolated pawn */
  3046.       PawnBonus = stage;
  3047.  
  3048.       KNIGHTPOST = (stage + 2) / 3;    /* knight near enemy pieces */
  3049.       KNIGHTSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  3050.  
  3051.       BISHOPSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  3052.       BishopBonus = BBONUS * stage;
  3053.  
  3054.       RHOPN = 10;        /* rook on half open file */
  3055.       RHOPNX = 4;
  3056.       RookBonus = RBONUS * stage;
  3057.  
  3058.       XRAY = 8;        /* Xray attack on piece */
  3059.       PINVAL = 10;        /* Pin */
  3060.  
  3061.       KHOPN = (3 * stage - 30) / 2;    /* king on half open file */
  3062.       KHOPNX = KHOPN / 2;
  3063.       KCASTLD = 10 - stage;
  3064.       KMOVD = -40 / (stage + 1);    /* king moved before castling */
  3065.       KATAK = (10 - stage) / 2;    /* B,R attacks near enemy king */
  3066.       KSFTY = ((stage < 8) ? (KINGSAFETY - 4 * stage) : 0);
  3067.  
  3068.       ATAKD = -6;        /* defender > attacker */
  3069.       HUNGP = -12;        /* each hung piece */
  3070.       HUNGX = -18;        /* extra for >1 hung piece */
  3071.       }
  3072. }
  3073.  
  3074. #endif